jsbi: JSON.stringify() doesn't know how to serialize a BigInt
Not certain how to handle this situation:
TypeError: Do not know how to serialize a BigInt
at JSON.stringify (<anonymous>)
39 | toObject() {
> 40 | return JSON.parse(JSON.stringify(this));
| ^
41 | }
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 20
- Comments: 17
@jakobkummerow Ok, makes sense. For anyone else stumbling upon this, the verified TL;DR fix for the above problem is:
Wouldn’t it be easier to just monkey patch (hijack)
BigInt
? That’s the MDN recommendation.If you do it this way, you don’t have to add an anonymous function into every call of
JSON.stringify
. It applies globally to all such calls.@phoenixbeats01 you can do this if you are using typescript
Or cleaner with the “I know what I do” feature:
Or better (for strict TS configs) with the TS declaration:
I found this solution more elegant, works for typescript too:
As somebody of you have commented before, you can put this into a file and import it to have it into the global scope with
import './utils.js'
.If you’re trying to use this with Typescript, I suggest you create a .ts or .js file with:
You can also return Number(this), but I suggest toString as it has no character limiter. However, it will depend on your context.
After that, you must import or require this file in your main file (like index.ts/.js or main.ts, etc).
If you are trying to run tests with Jest, you must add this file in the installation configuration. These settings can be created in package.json with “jest: { … }” or in a file called jest.config.ts (create this in the root).
Example:
At this point you can create a test module, with many configs, and create an index file that imports all the configs, and just pass this index file in the setupFiles config from jest.
Working as intended/spec’ed: https://tc39.es/proposal-bigint/#sec-serializejsonproperty (step 10).
In short, the background is that JSON is so commonly used among all sorts of different systems and programming languages that it is effectively impossible to add anything to the format without breaking compatibility in some crucial case.
You can define your own
.toJSON()
function, and pass a corresponding “reviver” function as an argument toJSON.parse()
. That way, at least you have control over any (backwards) compatibility issues.Element implicitly has an ‘any’ type because expression of type ‘“toJSON”’ can’t be used to index type ‘BigInt’. Property ‘toJSON’ does not exist on type ‘BigInt’.ts(7053)
I guess the process can be like this: stringify:
parse:
Hope this makes sense
This is it! Here i added a wrapper function:
JSON.parse(JSON.stringify(String(this)))
worked for me.The issue with serializing a BigInt as a string is that during the parsing you must know what any property is to know which ones should stay as strings and which ones should become big integers.
It would be better to use an approach similar to how BigNumber instances are stringified like this
I just added to bigNumberify support for BigInt values, so that the BigInt
125000n
will be encoded asand parsed back without ambiguities. Any feedback would be appreciated.
Polyfill:
Oh, I had
suppressImplicitAnyIndexErrors: true
in my config. Edited my example. Thanks!