question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add support for BigInt

See original GitHub issue

BigInt is one of the standard built-in types in Typescript. At the moment TypedJSON does not support parsing BigInt out of the box. The underlying problem is also that the standard JSON.parse() does not support parsing bigint - it coerces bigints into number, which loses precision.

Currently BigInt can be parsed by TypedJSON via custom de-/serializes and use of an external JSON parser that supports bigint parsing: https://github.com/sidorares/json-bigint.

Suggestion: add support for BigInts to TypedJSON

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
rjkz808commented, Jan 27, 2021

Personally, I think mapTypes is not the best way to do it. It can only accept BigInt constructor, so all the BigInt fields should be declared like that (as shown in README):

TypedJSON.mapType(BigInt, {
    deserializer: (value) => value == null ? value : BigInt(json),
    serializer: (value) => value == null ? value : value.toString(),
});

@jsonObject
class MyData {
    @jsonMember
    public amount: BigInt = BigInt(0);
}

But assigning BigInt type to the class field means it’ll be of type BigInt at compile-time, not a primitive bigint type. So, you can’t really use it in any calculations, because code like this will not compile:

const serializer = new TypedJSON(MyData);
const data = serializer.parse('{ "amount": "2" }');

if (!data) {
    throw new Error('Failed to parse data');
}

const x: bigint = BigInt(2);
console.log(data.amount + x); // The issue is here, x is a primitive 'bigint', and data.amount is 'BigInt'

So, to overcome this issue, I usually use something like this in my code:

function jsonBigIntMember(): PropertyDecorator {
    return jsonMember({
        deserializer: (json) => (json == null ? json : BigInt(json)),
        serializer: (value) => (value == null ? value : value.toString()),
    });
}

@jsonObject
class MyData {
    @jsonBigIntMember()
    public amount: bigint = BigInt(0); // Notice it's of type 'bigint' now
}

const serializer = new TypedJSON(MyData);
const data = serializer.parse('{ "amount": "2" }');

if (!data) {
    throw new Error('Failed to parse data');
}

const x: bigint = BigInt(2);
console.log(data.amount + x); // No compilation errors!
1reaction
MatthiasKunnencommented, Jan 19, 2021

I see where you’re coming from but do not believe we would support this anytime soon due to the need for using a custom JSON.parse method. Using the third-party JSON.parse library you mentioned has the following issues:

  • Increases bundle size
  • Only solves the problem for BigInt. If, for example, decimal is approved we will need another custom JSON.parse library for that or need to maintain our own. I would much prefer using the JSON.parse method provided by the browser or Node. Especially since it is likely to be faster and better tested.

Another thing to note is that while BigInt is a built-in type in TypeScript, it appears to only be available when targeting esnext.

Presenting precise numbers in JavaScript has long been an issue and will probably remain one for a while longer. Perhaps https://github.com/tc39/proposal-json-parse-with-source will solve these problems. In the meantime I strongly recommend to represent numbers outside of IEEE 754 precision as strings in JSON. If strings are used then the example shown above will preserve precision.

I’ve used the decimals represented by strings approach myself in applications that deal with money and can confirm it works perfectly. PayPal uses it too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

BigInt - JavaScript - MDN Web Docs
BigInt values represent numeric values which are too large to be represented by the number primitive.
Read more >
New in Access 2016—Large Number (BigInt) support - Microsoft
When creating new local tables or editing existing ones, Access now allows users to add fields that store BigInt numbers.
Read more >
BigInt - The Modern JavaScript Tutorial
BigInt is a special numeric type that provides support for integers of arbitrary length. ... Addition, c = a + b, c =...
Read more >
Is there anyway for IE11 to support BigInt? - Stack Overflow
No there is not. There were never plans for it to add Support for Internet Explorer and as Micrsoft drops support for IE...
Read more >
BigInt | Can I use... Support tables for HTML5, CSS3, etc
BigInt · Global · Chrome · Edge * · Safari · Firefox · Opera · IE · Chrome for Android.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found