Repository navigation
Allow Inifinity and -Infinity as number literal types #32277
Description
Activity
Also, to state the obvious in favour of this,
typeof Infinity = "number", not some odd object.Quizzically,
Infinityhas some odd type conversions internally that may be at the heart of this:type numberNames = {0: "zero", 1: "one", Infinity: "inf"}; type numberTypes = keyof numberNames; // These are fine: var zero:numberTypes = 0; var one:numberTypes = 1; // This is an expected error: var two:numberTypes = 2; /* ERROR var two: 0 | 1 | "Infinity" Type '2' is not assignable to type '0 | 1 | "Infinity"'. */ // This is an unexpected error: var inf:numberTypes = Infinity; /* ERROR var inf: 0 | 1 | "Infinity" Type 'number' is not assignable to type '0 | 1 | "Infinity"'. */
Here,
Infinityis treated as astring... not anumber, unlike the other number keys.So,
Infinitymight be treated just like any other simple string key here, at least.- addedAwaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript
on Jul 8, 2019 const Inf = 999e308; type Infinity = 999e999999; //Just for fun, it's still the same as `Inf` //We use `Inf` instead of `Infinity` type numberNames = {0: "zero", 1: "one", [Inf]: "inf"}; type numberTypes = keyof numberNames; // These are fine: var zero:numberTypes = 0; var one:numberTypes = 1; // This is an expected error: var two:numberTypes = 2; /* ERROR var two: 0 | 1 | "Infinity" Type '2' is not assignable to type '0 | 1 | "Infinity"'. */ // OK! var inf:numberTypes = Infinity as Infinity;
Reacted by Greg Hornby, Soichiro Miki, Shreyas Minocha, lionel-rowe-answer and Ian Bellomyshreyasminocha commented
on Nov 26, 2019 More actionsI have a very similar use case and was surprised that this doesn't work.
Also prevents you from making Infinity a mandatory key in a
Record:export type ImageSrcSet = Record<number, string> & { [Infinity]: string };
I'd expect that to resolve to a numeric dictionary where all keys are optional except for
Infinity. Instead, it triggers TS1170: a computed property name must be a literal type.I agree it makes sense to add
Infinityand-Infinity- these could be treated as top/bottom elements (pity we don't have orderings in types). And as with the reference from #44408, some operations have special behaviour forInfinity, so it would be handy to be able to describe this behaviour in the types.Reacted by Ricardo Fernández SerrataAdditional 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.
type D6 = 1|2|3|4|5|6|Infinity
Reacted by স্নেহাংশু ফুকন, Luna, Wes van Vugt and Michael PontusReacted by Ricardo Fernández SerrataMichalMarsalek commented
on Jan 12, 2023 ContributorMore actionsI also ran into this when implementing unbounded ranges, hoping that
bigint | Infinitywould be possible.I have been waiting for this for over 4 years.
Unless I'm missing something, (-)
Infinityis the only distinct primitive value that TypeScript cannot correctly treat in a literal type context. Aside fromNaN(which is not "distinct" in the first place), all primitive values, including bigints and symbols, can be correctly handled as a literal type. I personally think this is more of a defect than a feature request.Infinityis the only member of thenumbertype that is guaranteed to be larger than anybigint, which is important in some practical scenarios.Infinityis not some "error value" that arises from some unexpected calculation result, but is a fully-fledged constant whose behavior is strictly and rationally defined in the world of numerical computation in JavaScript.Reacted by Ricardo Fernández Serrata, Finn Voigtländer, Jacob Benison, esheyw, JonasDoe, Luna, Carlo Q, Glen Whitney, Jeremy Kelly and Nano Miratus / Anton StiglitzMy usecase for Infinity is a "flatten" utility accepting a depth of number including Infinity. It would be nice to overload for the case of
depth: Infinity. Creating a separate function or signature for this case would be expanding the api only to appease typescriptReacted by Luna, Brenton Simpson and Ricardo Fernández SerrataAs long as Infinity exists in JavaScript, I think people will find reasonable use cases for it from time to time, and TypeScript is limiting its utility for no good reason.
Today I wanted to write a function like
expiry(): Date | InfinityReacted by Soichiro MikiReacted by Ricardo Fernández Serrata, Luna and Jeremy KellyI have code/comments like the following for years. Would love to finally be able to do it the "right" way.
// Preferably use -Infinity(NegativeInfinity) and Infinity(PositiveInfinity) // once available as types // (see https://github.com/microsoft/TypeScript/issues/32277) value: DateTime | 'INFINITY';Reacted by Michal Maršálek and GouvernathorThe
Infinityconstant is not a JavaScript-only invention. It is a well-defined value from the IEEE 754 floating-point standard, which JavaScript (like many other languages) follows for itsnumbertype.The infinities of the extended real number line can be represented in IEEE floating-point datatypes, just like ordinary floating-point values like 1, 1.5, etc. They are not error values in any way, though they are often (depends on the rounding) used as replacement values when there is an overflow. Upon a divide-by-zero exception, a positive or negative infinity is returned as an exact result. An infinity can also be introduced as a numeral (like C's "INFINITY" macro, or "∞" if the programming language allows that syntax).
At the bit level,
Infinityis represented by a sign bit of0, an exponent of all ones (0x7FF), and a mantissa of all zeros:- Binary:
0 11111111111 0000000000000000000000000000000000000000000000000000 - Hex:
0x7FF0000000000000
Similarly,
-Infinityis simply0xFFF0000000000000.This means that
Infinityis not some exotic concept; it's a precise, stable value interoperable across major programming languages like C, Java, Python, and Go, via something likeFloat64Array. There is no reason not to support this technically well-grounded value as a literal type in TypeScript. In my opinion, not supporting this at the type level would mean math in TypeScript is not fully standard-compliant yet.Reacted by Daniel Bayley, Ondratra, Brenton Simpson, Luna, Marco Spiess and Sirz BenjieReacted by Martin Johns- Binary:
petamoriken commented
on Jun 29, 2025 ContributorMore actionsStage 2
Iterator.rangeseems to require theInfinitytype.type Infinity = number declare var Iterator: { new (): Iterator<never, void, void> prototype: Iterator<never, void, void> range(start: number, end: number, option: number | NumericRangeOptions<number>): IterableIterator<number> range(start: bigint, end: bigint | Infinity, option: bigint | NumericRangeOptions<bigint>): IterableIterator<bigint> } interface NumericRangeOptions<T extends bigint | number> { step?: T inclusive?: boolean }
https://github.com/tc39/proposal-iterator.range/blob/main/global.d.ts
Reacted by Soichiro Miki and Marco Spiess
Please accept
Infinityand-Infinityas valid number literal types.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
NaNas a literal type is tricky to implement,NaNandInfinityare not the same. And I have a clear use case forInfinityas a meaningful literal type, as shown above.Infinity is not tricky to compare
Unlike notorious
NaNor-0,Infinityworks just like an ordinary numeric constant as far as equality is concerned. We don't need a special function likeisNaN()orObject.is(). Ever since the ES5/IE6 era, there has been nothing counter-intuitive:Most importantly,
Infinity === Infinityis true (whileNaN === NaNis false). Unless I'm missing something, predictable equality is all that's required to safely useInfinityas a literal type, right? Even though the design note (#15356) says "there is more than one NaN, Infinity, etc", you can think ofInfinityin JavaScript as "just a fixed number" which happens to be larger thanNumber.MAX_VALUE.My use case
My library deals with unbounded (aka infinite) integer ranges, and I have been using
Infinityand-Infinitywithout 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 supportbigintin addition tonumber, and ran into this problem.You may ask "Why don't you just use string
'Infinity'orSymbol('unbounded')", butInfinityis a predefined and predictable constant, and it can be directly compared with any bigint (e.g.,10n ** 1000n < Infinityistrue). See how simple the implementation ofisValidcan be in the first example.PS: Looks like there is a hacky workaround (#31752), but I'd like to see the official support.