JSON.parse()
does not natively support BigInt
, and numbers exceeding Number.MAX_SAFE_INTEGER
lose precision. However, you can work around this by:
- Enquoting Large Numbers in JSON (turning them into strings before parsing).
- Using a Reviver Function in
JSON.parse()
to convert these strings intoBigInt
.
🔹 Step 1: Check If a Number is Too Large
const isBigNumber = num => !Number.isSafeInteger(+num);
🔹 Step 2: Modify JSON String to Preserve Large Numbers
const enquoteBigNumber = (jsonString, bigNumChecker) =>
jsonString.replaceAll(
/([:\s\[,]*)(\d+)([\s,\]]*)/g,
(match, prefix, num, suffix) =>
bigNumChecker(num) ? `${prefix}"${num}"${suffix}` : match
);
🔹 Step 3: Parse JSON & Convert Large Numbers to BigInt
const parseWithBigInt = (jsonString, bigNumChecker) =>
JSON.parse(
enquoteBigNumber(jsonString, bigNumChecker),
(key, value) => (!isNaN(value) && bigNumChecker(value) ? BigInt(value) : value)
);
🔹 Example Usage
Input JSON (containing large numbers)
const input = `{
"foo": [[0], [64], [89], [97]],
"bar": [
[2323866757078990912, 144636906343245838, 441695983932742154, 163402272522524744],
[2477006750808014916, 78818525534420994],
[18577623609266200],
[9008333127155712]
]
}`;
Parsing with BigInt
Conversion
const output = parseWithBigInt(input, isBigNumber);
Resulting Output
console.log("output.foo[1][0]:", output.foo[1][0], `(type: ${typeof output.foo[1][0]})`);
// Output: 64 (type: number)
console.log("output.bar[0][0]:", output.bar[0][0].toString(), `(type: ${typeof output.bar[0][0]})`);
// Output: 2323866757078990912 (type: bigint)
🔹 Why This Works
- ✔ Preserves precision by wrapping large numbers in quotes before parsing.
- ✔ Automatically detects large numbers using
Number.isSafeInteger()
. - ✔ Uses
BigInt
only for large numbers, keeping small numbers asNumber
.