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

NaN, Infinity and -Infinity not accepted in number literal types #15135

Closed
olivr70 opened this issue Apr 11, 2017 · 1 comment · May be fixed by #51741
Closed

NaN, Infinity and -Infinity not accepted in number literal types #15135

olivr70 opened this issue Apr 11, 2017 · 1 comment · May be fixed by #51741
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds

Comments

@olivr70
Copy link

olivr70 commented Apr 11, 2017

TypeScript Version: 2.2.2

Code

// A *self-contained* demonstration of the problem follows...
let a : 0 | 1 / compiles
let b : 0 | NaN // fails : Cannot find name 'NaN'
let b : 0 | Inifinity // fails : Cannot find name 'Inifinity'
let b : 0 | -Inifinity // fails : Cannot find name '-Inifinity'

Expected behavior:
Well, NaN, +Infinity and -Infinity are valid numbers, so I see no reason they should not be accepted

Actual behavior:
It fails to compile

** Benefits **
I discovered this was all discussed in #9407. @ahejlsberg and @weswigham explicetly took position against including it, except for a compelling case...

Other than being the intuitive result (why on earth a perfectly valid number would not be acceptable a in a number literal type, I see several benefits :

One application would be the Math.sign() type definition. It is currently defined as returning a number although the spec says it can only return 0 | -0 | +1 | 1 | NaN
This is in fact how I got into the problem : I wanted to implement a comparator function (returning -1|0|1) using Math.sign( ), intuitively expecting to be limited to those 3 values (and at the time forgetting about NaN)

To continue with the Math.sign, it could be defined as follows

interface Math {
  sign(x:NaN):NaN
  sign(x:number):0|1|-1
}

This way, it explicitely states when the function returns NaN and be extremely useful for documentation purposes (I suppose modifying a compiler for documentation is not very strong...)

Another one I can see (although it's a quick thought) : I think it could provide very interesting handling of NaN (if we had substraction types #4183)

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Apr 11, 2017
@RyanCavanaugh RyanCavanaugh added Too Complex An issue which adding support for may be too complex for the value it adds and removed In Discussion Not yet reached consensus labels Apr 24, 2017
@RyanCavanaugh
Copy link
Member

it explicitely states when the function returns NaN and be extremely useful for documentation purpose

Basically comes down to this. The first signature there would only ever be hit when writing exactly Math.sign(NaN), which... why would you ever do that (or anything equivalent where you already know that a value is NaN).

A secondary objection is that NaN is not semantically a unit type the same way 0 is -- any number of different invalid operations produce NaN; this is also somewhat true of Infinity. NaN's odd behavior with === would also introduce a bunch of extra logic in how we narrow.

@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
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

Successfully merging a pull request may close this issue.

2 participants