Typescript: Issue an error when numeric literals can incur precision loss

Created on 11 Feb 2019  路  10Comments  路  Source: microsoft/TypeScript

In JavaScript, you can write out a really really big (non-bigint) integer literal and get a completely different value.

0x6A09E667F3BCC908n == 0x6A09E667F3BCC908n // true

0x6A09E667F3BCC908n == 0x6A09E667F3BCC908  // false!?

It's worth asking whether or not a really really big integer values which have different observed and specified values are erroneous, and whether we can give users an error.

This would be a breaking change, but it's not clear who benefits from the current behavior.

See https://github.com/tc39/proposal-bigint/issues/170 for where this came up (CC @littledan)

Declined Suggestion

Most helpful comment

We don't have warnings - just errors 馃槃馃敟馃寧馃敟馃槃

All 10 comments

This is a great idea! However, this behavior been part of JS forever, so it might be good to start with a warning and see how it goes.

We don't have warnings - just errors 馃槃馃敟馃寧馃敟馃槃

Which behavior will be accepted?

  1. numerical compare to bigint literal
  2. numerical literal compare to bitint literal
  3. numerical literal compare to bigint
  4. numerical literal compare to bigint literal

It's actually not about the comparisons themselves - it's about writing out an integer numeric literal whose value is too large to be represented accurately. In this specific case, I think we'd expect to error on a number like 0x6A09E667F3BCC908 with

This numeric literal's value is too large to be represented accurately as an integer.

I don't necessarily think we'd want the error for any numeric literal with a fractional component (e.g. no error on 9000000000000000000000000000.000000009).

This numeric literal's value is too large to be represented accurately as an integer.

This is nice, but most don't know that 253 is the maximum for these. Perhaps a friendly error message would be something like:

Numeric literal values equal to 2^53 or greater are too large to be represented accurately as an integer.

This is a great idea! However, this behavior been part of JS forever, so it might be good to start with a warning and see how it goes.

How about a quick fix to add an n to the end of the numeric literal, if possible?

Feel free to add a quick fix to insert the bigint suffix.

Feels like this is better off as some sort of lint rule. 馃槩

Thanks for the PR though @JoshuaKGoldberg.

IMO if I write out a numeric literal in the source text and assign it to a variable, without manipulating it in any way, and then observe a different value at runtime, I would wonder why the compiler didn鈥檛 yell at me (after spending probably several minutes debugging it :P)

Only literals which can be exactly represented should be accepted.

(Note that a codefix to change large numbers to bigint isn鈥檛 necessarily safe - mixing them with regular numbers in operations will produce runtime errors.)

Then again, 1.1 can鈥檛 be exactly represented in IEEE double either so it then becomes a question of how much precision loss you want to accept. Hmm.

Also huge numbers like 1e100 would likely be errors too since it鈥檚 unlikely they won鈥檛 be rounded... nevermind, I take it back, this is a terrible idea. :stuck_out_tongue:

I agree with @DanielRosenwasser, this is a job for a lint tool, not the compiler.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uber5001 picture uber5001  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

bgrieder picture bgrieder  路  3Comments

siddjain picture siddjain  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments