Skip to content

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 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.

Activity

  1. mathiasbynens commented on Nov 30, 2018

    @mathiasbynens
    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.

  2. weswigham commented on Nov 30, 2018

    @weswigham
    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.

  3. added
    DeclinedThe issue was declined as something which matches the TypeScript vision
    Too ComplexAn issue which adding support for may be too complex for the value it adds
    SuggestionAn idea for TypeScript
    on Nov 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions