📄 js-yaml/examples/int_type_override

File: int_type_override.md | Updated: 11/15/2025

Integer Type Override - Using BigInt

This example demonstrates how to override the built-in !!int type to use JavaScript's BigInt instead of Number for representing integers.

Overview

By default, JS-YAML represents integers as JavaScript Number values, which can only safely represent integers up to Number.MAX_SAFE_INTEGER (2^53 - 1). This example shows how to override the integer type to use BigInt for arbitrary precision integers.

Why BigInt?

JavaScript's BigInt type can represent integers of arbitrary size, making it perfect for:

  • Very large integers beyond the safe integer range
  • Financial calculations requiring exact precision
  • Working with 64-bit integers from other systems
  • Cryptographic operations

Implementation

Step 1: Copy Original Options

let options = Object.assign({}, yaml.types.int.options);

Start with the original integer type options to preserve most of the built-in behavior.

Step 2: Override the Constructor

options.construct = data => {
  let value = data, sign = 1n, ch;

  if (value.indexOf('_') !== -1) {
    value = value.replace(/_/g, '');
  }

  ch = value[0];

  if (ch === '-' || ch === '+') {
    if (ch === '-') sign = -1n;
    value = value.slice(1);
    ch = value[0];
  }

  return sign * BigInt(value);
};

This function:

  • Removes underscores used as digit separators (e.g., 1_000_000)
  • Handles the sign (+ or -)
  • Converts the string to a BigInt
  • Returns a signed BigInt value

Step 3: Update the Predicate

options.predicate = object => {
  return Object.prototype.toString.call(object) === '[object BigInt]' ||
         yaml.types.int.options.predicate(object);
};

The predicate determines if a JavaScript value should be represented as this type when dumping. It now accepts both BigInt and regular Number values.

Step 4: Create the Type and Schema

let BigIntType = new yaml.Type('tag:yaml.org,2002:int', options);

const SCHEMA = yaml.DEFAULT_SCHEMA.extend({ implicit: [ BigIntType ] });

Note the use of implicit instead of explicit - this replaces the default integer type rather than adding a new tagged type.

Example Usage

const data = `
bigint: -12_345_678_901_234_567_890
`;

const loaded = yaml.load(data, { schema: SCHEMA });

console.log('Parsed as:');
console.log('-'.repeat(70));
console.log(util.inspect(loaded, false, 20, true));

console.log('');
console.log('');
console.log('Dumped as:');
console.log('-'.repeat(70));
console.log(yaml.dump(loaded, { schema: SCHEMA }));

Output

Parsed as:

{ bigint: -12345678901234567890n }

Note the n suffix indicating a BigInt value.

Dumped as:

bigint: -12345678901234567890

Complete Code

'use strict';

const util = require('util');
const yaml = require('../');

// keep most of the original `int` options as is
let options = Object.assign({}, yaml.types.int.options);

options.construct = data => {
  let value = data, sign = 1n, ch;

  if (value.indexOf('_') !== -1) {
    value = value.replace(/_/g, '');
  }

  ch = value[0];

  if (ch === '-' || ch === '+') {
    if (ch === '-') sign = -1n;
    value = value.slice(1);
    ch = value[0];
  }

  return sign * BigInt(value);
};

options.predicate = object => {
  return Object.prototype.toString.call(object) === '[object BigInt]' ||
         yaml.types.int.options.predicate(object);
};

let BigIntType = new yaml.Type('tag:yaml.org,2002:int', options);

const SCHEMA = yaml.DEFAULT_SCHEMA.extend({ implicit: [ BigIntType ] });

const data = `
bigint: -12_345_678_901_234_567_890
`;

const loaded = yaml.load(data, { schema: SCHEMA });

console.log('Parsed as:');
console.log('-'.repeat(70));
console.log(util.inspect(loaded, false, 20, true));

console.log('');
console.log('');
console.log('Dumped as:');
console.log('-'.repeat(70));
console.log(yaml.dump(loaded, { schema: SCHEMA }));

Important Notes

  • BigInt literals use the n suffix in JavaScript (e.g., 1n)
  • You cannot mix BigInt and Number in arithmetic operations without explicit conversion
  • BigInt is supported in Node.js 10.4.0+ and modern browsers
  • The original integer parsing logic (hex, octal, binary) is preserved

Use Cases

This pattern can be applied to override other built-in types:

  • Custom date/timestamp parsing
  • Special handling for floats (Decimal.js, etc.)
  • Custom string escaping rules
  • Modified boolean representations