Repository navigation
BigInt downleveling/polyfilling/transpiling — integrate with JSBI? #28756
Description
Search Terms
bigint
Suggestion
I was excited to see BigInt support in TypeScript 3.2 ♥ I also read the relevant announcement, and this part caught my eye: https://blogs.msdn.microsoft.com/typescript/2018/11/29/announcing-typescript-3-2/#bigint
As we mentioned, BigInt support is only available for the
esnexttarget. It may not be obvious, but because BigInts have different behavior for mathematical operators like+,-,*, etc., providing functionality for older targets where the feature doesn’t exist (likees2017and below) would involve rewriting each of these operations. TypeScript would need to dispatch to the correct behavior depending on the type, and so every addition, string concatenation, multiplication, etc. would involve a function call.For that reason, we have no immediate plans to provide downleveling support. On the bright side, Node 11 and newer versions of Chrome already support this feature, so you’ll be able to use BigInts there when targeting
esnext.
We very recently launched the JSBI library which serves as a spec-compliant BigInt polyfill. So recently in fact, I imagine it may not yet have been considered by the TypeScript team. (It it was, and you already decided against it, then please feel free to close this issue immediately!)
Here’s the thing: instead of native BigInt code, TypeScript could choose to produce JSBI code for the es2017 target and below. That would enable TypeScript users to write BigInt code and have it be transpiled conditionally depending on their configured target.
I believe this might be possible because unlike Babel, TypeScript actually knows which variables represent BigInts instead of other types. Therefore, it seems TypeScript could avoid wrapping every single operator in a function call — it would only do so for operations that TypeScript know involve a BigInt.
Please correct me if I’m wrong and feel free to close this issue if my assumptions don’t make sense.
Use Cases
BigInt functionality is currently only available when targeting esnext. Outputting JSBI for the es2017 target and older would at least enable the functionality in current/older environments other than recent versions of Chrome and Node.js.
Examples
Native BigInt code:
const max = BigInt(Number.MAX_SAFE_INTEGER);
const two = 2n;
const result = max + two;
console.log(result);
// → '9007199254740993'Equivalent JSBI code (works in all modern browsers):
const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
const two = JSBI.BigInt('2');
const result = JSBI.add(max, two);
console.log(result.toString());
// → '9007199254740993'Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Activity
mathiasbynens commentedon Nov 30, 2018
For the record, I’m aware that https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals states:
This proposal might very well fall under this bucket. However, given that a) BigInt is an exceptional case, and b) TypeScript seems to be in the unique position to have the necessary type tracking information needed to efficiently transform native BigInts to library code, this might be a worthy exception to the rule. This is an opportunity to enable developers to use and ship BigInts everywhere, today.
weswigham commentedon Nov 30, 2018
We're aware that
bigintpolyfill libraries exist. We won't downlevel to one because type directed emit is unreliable (we have theanytype and casting), inefficient, and prevents compartmentalized typechecking/emit of a program. And we won't do it in a non-directed way because, as stated, it requires overwriting all mathematical function operations with function calls that perform argument runtime type checks.If you really need downlevel big integer support, you should probably just be using one of the bigint libraries directly.