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

Broken emit when Infinity or ‑Infinity ends up in a type position #42905

Open
ExE-Boss opened this issue Feb 21, 2021 · 6 comments · May be fixed by #51741
Open

Broken emit when Infinity or ‑Infinity ends up in a type position #42905

ExE-Boss opened this issue Feb 21, 2021 · 6 comments · May be fixed by #51741
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Milestone

Comments

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Feb 21, 2021

Bug Report

🔎 Search Terms

  • Infinity
  • NaN
  • numeric
  • literal

🕗 Version & Regression Information

💻 Code

// @declaration
// @showEmit
// @showEmittedFile: index.d.ts

// @filename: index.ts
export const PositiveInfinity: 1e1_000_000 = 1/0 as any;
export const NegativeInfinity: -1e1_000_000 = -1/0 as any;

⏯ Playground Link

Workbench Repro

🙁 Actual behavior

TypeScript emits Infinity and ‑Infinity in a type position, which are intentionally invalid according to #9407 (comment):

// index.d.ts
export const PositiveInfinity: Infinity;
export const NegativeInfinity: -Infinity;

🙂 Expected behavior

The Infinity and ‑Infinity values are valid in a type position, so that the generated .d.ts file is valid.


Also, it’d be nice to support literal NaNs, which would allow for Number.isNaN to be typed as:

interface NumberConstructor {
	isNaN(number: unknown): number is NaN;
}

Related issues

@ExE-Boss ExE-Boss changed the title Broken emit when Infinity or -Infinity ends up in a Type position Broken emit when Infinity or ‑Infinity ends up in a type position Feb 21, 2021
@MartinJohns
Copy link
Contributor

MartinJohns commented Feb 21, 2021

You're mixing a bug report and a feature request together in one. Fixing the bug would be to emit the type number instead of Infinity. Introducing an Infinity (and NaN) type is a feature request, for which you should provide a good reasoning in response to #9407 (comment).

@Jamesernator
Copy link

I for one have wanted Infinity/-Infinity as a special case for things that otherwise take BigInts e.g. ranges:

function* bigintRange(low: bigint, high: bigint | Infinity, step?: bigint=1n): Generator<bigint> {
  for (let i = low; i < high; i += step) {
    yield i;
  }
}

@MartinJohns
Copy link
Contributor

@Jamesernator Just as a general advice: It tremendously helps when you explain your reasoning on why you want this, not just say "I want it for this". In your example you could just as well replace the Infinity with undefined. Having a dedicated Infinity type would not help you in this case, because Infinity would be a sub-type of number, so the union type number | Infinity would be simplified to number. Same as it happens with number | 5.

@Jamesernator
Copy link

Jamesernator commented Feb 22, 2021

In your example you could just as well replace the Infinity with undefined. Having a dedicated Infinity type would not help you in this case, because Infinity would be a sub-type of number, so the union type number | Infinity would be simplified to number.

The example is bigint not number. BigInts don't contain an Infinity value, I think it's a lot more readable to use the explicit Infinity value rather than some arbitrary token as it already compares correctly with bigints (e.g. bigint < Infinity is always true, no coercion to Number happens).

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Feb 22, 2021
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Feb 22, 2021
@ca-d
Copy link

ca-d commented Apr 23, 2021

@Jamesernator Just as a general advice: It tremendously helps when you explain your reasoning on why you want this, not just say "I want it for this". In your example you could just as well replace the Infinity with undefined. Having a dedicated Infinity type would not help you in this case, because Infinity would be a sub-type of number, so the union type number | Infinity would be simplified to number. Same as it happens with number | 5.

More compelling explanations for why these types are needed can be found in #28682 .

@graphemecluster graphemecluster linked a pull request Dec 4, 2022 that will close this issue
@typescript-bot typescript-bot added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label Dec 3, 2023
@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 4, 2023

👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript.


Issue body code block by @ExE-Boss

👍 Compiled
Emit:

export declare const PositiveInfinity: Infinity;
export declare const NegativeInfinity: -Infinity;

Historical Information
Version Reproduction Outputs
4.9.3, 5.0.2, 5.1.3, 5.2.2, 5.3.2

👍 Compiled
Emit:

export declare const PositiveInfinity: Infinity;
export declare const NegativeInfinity: -Infinity;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants