12

I'm looking for a way to force JSON.stringify to always print BigInts without complaining.

I know it's non-standard, I know there's a package for that in pure JavaScript; but it doesn't fit my needs. I even know a fix in raw JavaScript by setting BigInt.prototype.toJSON. What I need is some way to override the normal JSON.stringify function globally in my TypeScript code.

I had found the following code, a year or so ago:

declare global
{
    interface BigIntConstructor
    {
        toJSON:()=>BigInt;
    }
}

BigInt.toJSON = function() { return this.toString(); };

on some web page I can't manage to find again. It used to work in another project of mine, but it doesn't seem to work any more. I have no idea why.

No matter what I do to the lines above, if I try to print a JSON containing a BigInt, I get: TypeError: Do not know how to serialize a BigInt.

Any help is appreciated - many thanks in advance.

Tristan Duquesne
  • 512
  • 1
  • 6
  • 16
  • Shouldn't `toJSON:()=>BigInt` be `toJSON:(num: BigInt)=>string`? – Anatoly Dec 05 '20 at 10:15
  • Asked myself the very same question when I discovered that code snippet. It didn't work then; it doesn't work now (it's one of the thing I tested as a sanity check...). This code snippet still mystifies me. Btw, I experimented some more, and I think the reason why it doesn't work anymore might be linked to my `tsconfig.json`; but I'm not sure what I'd need to do to have it work again; and if it's even compatible with my current "target" needs. – Tristan Duquesne Dec 05 '20 at 16:56

3 Answers3

15

You could use the replacer argument for JSON.stringify like this:

const obj = {
  foo: 'abc',
  bar: 781,
  qux: 9n
}

JSON.stringify(obj, (_, v) => typeof v === 'bigint' ? v.toString() : v)
Alex Chashin
  • 3,129
  • 1
  • 13
  • 35
8

This is what you looking for:

BigInt.prototype.toJSON = function() { return this.toString() }

https://github.com/GoogleChromeLabs/jsbi/issues/30#issuecomment-953187833

  • 5
    This works with pure JavaScript, but not TypeScript. Compiling with tsc gives error TS2339: Property 'toJSON' does not exist on type 'BigInt'. – Bruce Dec 29 '21 at 08:42
  • 3
    There's a TypeScript solution in that link if you keep reading: https://github.com/GoogleChromeLabs/jsbi/issues/30#issuecomment-1006088574 – Adam Spiers Jul 08 '22 at 02:09
2

I needed to get JSON.stringify to work in one of the dependencies, so I couldn't use the above answer. Instead, I created a patch.js file:

BigInt.prototype.toJSON = function() {
    return this.toString()
} 

Then at the beginning of my TypeScript source I added:

require('patch.js')

After that, JSON.stringify could handle BigInts without any problems.

Bruce
  • 449
  • 4
  • 6