Allow Inifinity and -Infinity as number literal types
See original GitHub issuePlease accept Infinity
and -Infinity
as valid number literal types.
/** A range of BigInt that may be unbounded, e.g., (-∞, 5] */
class BigIntRange {
public min: bigint | -Infinity = 0n; // <= Error!
public max: bigint | Infinity = 1n; // <= Error!
public isValid(): boolean {
return this.min <= this.max;
}
}
Currently, This causes a compile error, 'Infinity' refers to a value, but is being used as a type here. (2749)
.
I understand this was once rejected as part of #15135 and #15356, and the given reasons were: 1) difficult to implement, and 2) lacks a compelling use case.
However, while I understand why NaN
as a literal type is tricky to implement, NaN
and Infinity
are not the same. And I have a clear use case for Infinity
as a meaningful literal type, as shown above.
Infinity is not tricky to compare
Unlike notorious NaN
or -0
, Infinity
works just like an ordinary numeric constant as far as equality is concerned. We don’t need a special function like isNaN()
or Object.is()
. Ever since the ES5/IE6 era, there has been nothing counter-intuitive:
Infinity === Infinity // => true
-Infinity === -Infinity // => true
Number.POSITIVE_INFINITY === Infinity // => true
Object.is(-Infinity, Number.NEGATIVE_INFINITY) // => true
10 ** 500 === Infinity // => true (because 10**500 is above Number.MAX_VALUE)
typeof Infinity === 'number' // => true
typeof Number.NEGATIVE_INFINITY === 'number' // => true
// FWIW, comparison works just as expected, too
50 < Infinity // => true
-Infinity < 50; // => true
10n ** 500n < Infinity // => true
Number.MAX_VALUE < Infinity // => true
Infinity < Infinity // => false
Most importantly, Infinity === Infinity
is true (while NaN === NaN
is false). Unless I’m missing something, predictable equality is all that’s required to safely use Infinity
as a literal type, right? Even though the design note (#15356) says “there is more than one NaN, Infinity, etc”, you can think of Infinity
in JavaScript as “just a fixed number” which happens to be larger than Number.MAX_VALUE
.
My use case
My library deals with unbounded (aka infinite) integer ranges, and I have been using Infinity
and -Infinity
without any issue to denote what they literally mean, infinity in the mathematical sense. I have instructed my users to use these interesting constants, too. Recently I started to extend my library to support bigint
in addition to number
, and ran into this problem.
You may ask “Why don’t you just use string 'Infinity'
or Symbol('unbounded')
”, but Infinity
is a predefined and predictable constant, and it can be directly compared with any bigint (e.g., 10n ** 1000n < Infinity
is true
). See how simple the implementation of isValid
can be in the first example.
PS: Looks like there is a hacky workaround (#31752), but I’d like to see the official support.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:72
- Comments:7 (1 by maintainers)
Top GitHub Comments
Playground
Additional silly (?) use case:
Consider a roleplaying game where players roll a dice against an unconstrained difficulty number.
You’d like a type that includes the possible die results plus an ‘auto-succeed’ value for peculiar circumstances, e.g.