question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow Inifinity and -Infinity as number literal types

See original GitHub issue

Please 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:open
  • Created 4 years ago
  • Reactions:72
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
AnyhowStepcommented, Jul 17, 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;

Playground

4reactions
IanBellomycommented, Jul 10, 2021

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.

type D6 = 1|2|3|4|5|6|Infinity
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use conditional types on NaN and Infinity
How to use conditional types on NaN and Infinity · TypeScript does not have numeric literal types corresponding to NaN or Infinity or...
Read more >
Handbook - Literal Types - TypeScript
Using literal types with TypeScript. ... The process of going from an infinite number of potential cases (there is an infinite number of...
Read more >
Numeric Literals - ActionScript: The Definitive Guide [Book]
The number type supports three kinds of literals: integer literals, ... Minimum Allowed Value, Maximum Allowed Value, Infinity, and Negative Infinity.
Read more >
Infinity - JavaScript - MDN Web Docs
Infinity. The global property Infinity is a numeric value representing infinity. Try it.
Read more >
Infinity in Python - Represent an Infinite Number in Python
In Python, there is no way or method to represent infinity as an integer. This matches the fundamental characteristic of many other popular...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found