BigInt and Number conversions
When working with numbers in JavaScript there are two primitive types to choose from - BigInt and Number. One could expect implicit conversion from "smaller" type to "bigger" type which isn't a case in JavaScript.
Expected
When puting some bination of BigInt and Number user could expect implicit cast from Number to BigInt like in below example:
const number = 16n + 32; // DOESN'T WORK
// Expected: Evaluates to 48n
Actual behavior
Expressions operating on both BigInt and Number are throwing an error:
const number = 16n + 32;
// Throws "TypeError: Cannot mix BigInt and other types, use explicit conversions"
Why explicit conversion is needed in above cases?
Or in other words what is the reason behind this design?
BigInt and Number conversions
When working with numbers in JavaScript there are two primitive types to choose from - BigInt and Number. One could expect implicit conversion from "smaller" type to "bigger" type which isn't a case in JavaScript.
Expected
When puting some bination of BigInt and Number user could expect implicit cast from Number to BigInt like in below example:
const number = 16n + 32; // DOESN'T WORK
// Expected: Evaluates to 48n
Actual behavior
Expressions operating on both BigInt and Number are throwing an error:
const number = 16n + 32;
// Throws "TypeError: Cannot mix BigInt and other types, use explicit conversions"
Why explicit conversion is needed in above cases?
Or in other words what is the reason behind this design?
Share Improve this question edited Nov 21, 2023 at 16:14 user894319twitter 1 asked Sep 18, 2019 at 16:12 M. TwarogM. Twarog 2,6314 gold badges23 silver badges42 bronze badges 1-
One motivation might also be speed,. coercion does e at a cost. If the V8 or whatever Javascript engine can enforce
typeof value = 'bigint'
no extra check's are required. – Keith Commented Sep 18, 2019 at 16:32
4 Answers
Reset to default 3This is documented in the original BigInt proposal: https://github./tc39/proposal-bigint/blob/master/README.md#design-goals-or-why-is-this-like-this
When a messy situation es up, this proposal errs on the side of throwing an exception rather than rely on type coercion and risk giving an imprecise answer.
It's a design choice. In statically typed languages, coercion might give loss of information, like going from float to int the fractional part just gets truncated. JavaScript does type coercion and you may expect 16n + 32 to just use 32 as if it were a BigInt instead of a Number and there wouldn't be a problem. This was purely a design choice which is motivated here in this part of the documentation
They are not "smaller" and "bigger". One has real but potentially imprecise numbers, the other has integral but precise ones. What do you think should be the result of 16n + 32.5
? (note that type-wise, there is no difference between 32
and 32.5
). Automatically converting to BigInt will lose any fractional value; automatically converting to Number will risk loss of precision, and potential overflow. The requirement for explicit conversion forces the programmer to choose which behaviour they desire, without leaving it to chance, as a potential (very likely) source of bugs.
You probably missed an important point:
BigInt is about integers
Number is about real numbers
Implicit conversion from 32 to 32n might have sense, but implicit conversion from floating point number e.g. 1.555 to BigInt would be misleading.