TypeScript: Serialize BigInt in JSON
Working with large numbers in JavaScript often necessitates using the BigInt
data type. However, when it comes to serializing these numbers into JSON, you might encounter challenges because JSON natively only supports numbers within the safe integer range. This article explores the problem of serializing BigInt
values in JSON, explains the underlying issue, and provides practical solutions to overcome this hurdle.
The Challenge
Let's consider a scenario where we have a BigInt
representing a large number and we want to store it in JSON format.
const largeNumber = 99999999999999999999n;
const jsonData = {
value: largeNumber,
};
// Serializing to JSON
const jsonString = JSON.stringify(jsonData);
console.log(jsonString); // Output: {"value":99999999999999999999}
The output clearly shows that the serialized JSON does not retain the BigInt
nature of the value
. The resulting JSON string simply shows the number as a regular JavaScript number, potentially leading to data loss or unexpected behavior when deserializing.
Why this happens:
The primary reason behind this behavior lies in the fundamental differences between JSON and JavaScript's BigInt
type. JSON, as a standardized data format, does not have a dedicated representation for BigInt
values. The JSON parser treats the BigInt
as a regular number and might truncate it if it exceeds the safe integer range.
Solutions
Fortunately, we can employ various strategies to overcome this limitation:
-
String Conversion:
The most straightforward approach involves converting the
BigInt
to a string before serialization. This preserves the original value, ensuring its integrity when deserializing:const largeNumber = 99999999999999999999n; const jsonData = { value: largeNumber.toString(), }; const jsonString = JSON.stringify(jsonData); console.log(jsonString); // Output: {"value":"99999999999999999999"}
Note: When deserializing, you'll need to convert the string back to a
BigInt
usingBigInt(jsonString.value)
for accurate representation. -
Custom Serialization:
For more complex scenarios, consider creating a custom serialization function that handles
BigInt
values differently:const serializeBigInt = (obj: any): any => { if (typeof obj === 'bigint') { return obj.toString(); } if (typeof obj === 'object') { const newObj = {}; for (const key in obj) { newObj[key] = serializeBigInt(obj[key]); } return newObj; } return obj; }; const largeNumber = 99999999999999999999n; const jsonData = { value: largeNumber, }; const jsonString = JSON.stringify(jsonData, serializeBigInt); console.log(jsonString); // Output: {"value":"99999999999999999999"}
This approach offers greater control over the serialization process and ensures proper handling of
BigInt
values.
Conclusion
While JSON doesn't have native support for BigInt
, utilizing appropriate techniques like string conversion or custom serialization functions allows you to seamlessly manage BigInt
values within JSON structures. Choose the method that best suits your specific needs and application context.
References and Resources:
By understanding these techniques and applying them effectively, you can confidently leverage BigInt
values while working with JSON in TypeScript.