Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BigInt downleveling/polyfilling/transpiling — integrate with JSBI? #28756

Closed
2 of 5 tasks
mathiasbynens opened this issue Nov 30, 2018 · 2 comments
Closed
2 of 5 tasks
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds

Comments

@mathiasbynens
Copy link

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 esnext target. 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 (like es2017 and 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.
@mathiasbynens
Copy link
Author

For the record, I’m aware that https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals states:

Provide additional runtime functionality or libraries. Instead, use TypeScript to describe existing libraries.

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
Copy link
Member

We're aware that bigint polyfill libraries exist. We won't downlevel to one because type directed emit is unreliable (we have the any type 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.

@weswigham weswigham added Declined The issue was declined as something which matches the TypeScript vision Too Complex An issue which adding support for may be too complex for the value it adds Suggestion An idea for TypeScript labels Nov 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds
Projects
None yet
Development

No branches or pull requests

2 participants