How to serialize 64-bit integer in JavaScript?
This is actually a lot harder than it seems.
Representing big integers in JavaScript can be done using the BigInt
data type (by suffixing the number with n
), which is fairly widely supported at this point.
This would make your object look like this:
const o = { span_id: 16956440953342013954n, trace_id: 13756071592735822010n};
The problem presents itself in the JSON serialization, as there is currently no support for the serialization of BigInt
objects. And when it comes to JSON serialization, your options for customization are very limited:
- The
replacer
function that can be used withJSON.stringify()
will let you customize the serialization behavior forBigInt
objects, but will not allow you to serialize them as a raw (unquoted) string. - For the same reason, implementing the
toJSON()
method on theBigInt
prototype will also not work. - Due to the fact that
JSON.stringify()
does not seem to recursively call itself internally, solutions that involve wrapping it in a proxy also will not work.
So the only option that I can find is to (at least partially) implement your own JSON serialization mechanism.
This is a very poor man's implementation that calls toString()
for object properties that are of type BigInt
, and delegates to JSON.stringify()
otherwise:
const o = { "span_id": 16956440953342013954n, "trace_id": 13756071592735822010n};const stringify = (o) => '{' + Object.entries(o).reduce((a, [k, v]) => ([ ...a, `"${k}": ${typeof v === 'bigint' ? v.toString() : JSON.stringify(v)}` ])).join(', ') + '}';console.log(stringify(o));
Note that the above will not work correctly in a number of cases, most prominently nested objects and arrays. If I were to do this for real-world usage, I would probably base myself on Douglas Crockford's JSON implementation. It should be sufficient to add an additional case around this line:
case "bigint": return value.toString();