poppinss/utils

Better support for BigInt inside JSON utils

Closed this issue · 2 comments

Why this feature is required (specific use-cases will be appreciated)?

Currently, safeStringify/fast-safe-stringify serialize BigInt values to strings instead of JSON numbers. I know this is a limitation of the native JavaScript JSON library, but the JSON spec doesn't have this limitation. I suggest using true-json-bigint, which is a custom serializer/deserializer that supports it.

Before:

const data = {smallInt: 1, bigInt: 987654321123456789987654321n}
const result = JSON.stringify(data)

console.log(result)
// {"smallInt": 1, "bigInt": "987654321123456789987654321"}

const parsed = JSON.parse(result)

console.log(typeof parsed.smallInt)
// number

console.log(typeof parsed.bigInt)
// string

After:

const JSONbig = require('true-json-bigint')({useNativeBigInt: true})

const data = {smallInt: 1, bigInt: 987654321123456789987654321n}
const result = JSONbig.stringify(data)

console.log(result)
// {"smallInt": 1, "bigInt": 987654321123456789987654321}

const parsed = JSONbig.parse(result)

console.log(typeof parsed.smallInt)
// number

console.log(typeof parsed.bigInt)
// BigInt

Have you tried any other work arounds?

Yes, there is no native way for JSON.stringify to output BigInts to a number instead of string.

Are you willing to work on it with little guidance?

Yes, although I don't know how to make tests.

Update: I found a better fork that is native TypeScript, and can also serve as a drop-in replacement for the built-in JSON library: https://www.npmjs.com/package/json-big

New example code:

import JSONBig from 'json-big'
const JSON = JSONBig({ useNativeBigInt: true })

const data = { smallInt: 1, bigInt: 987654321123456789987654321n }
const result = JSON.stringify(data)

console.log(result)
// {"smallInt":1,"bigInt":987654321123456789987654321}

const parsed = JSON.parse(result)

console.log(typeof parsed.smallInt)
// number

console.log(typeof parsed.bigInt)
// BigInt

Sorry for the late reply. I have to sit on it for a while and read a little bit about the topic.

So the landscape of BigInt is not really standarized and everyone will roll out their own version of serialization and de-serialization.

The json-big library does a great job in converting the values to a number. But they have a handwritten parser. Something I do not want to use as of now without knowing all the downsides of it.

Also, if the server stringifies the BigInt values to a number. The client needs the same json-big library to convert those numbers into BigInt.


I will make no changes to the stringify logic for now and instead let the end user decide the BigInt treatment using the replacer function.