Skip to content

Fix NaN-valued enum members creating distinct literal types#3932

Open
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-nan-valued-enum-type
Open

Fix NaN-valued enum members creating distinct literal types#3932
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-nan-valued-enum-type

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

Go maps use IEEE 754 equality for key comparison, where NaN != NaN. This means map lookups with NaN keys always miss, causing each NaN-valued enum member to get a distinct literal type.

enum E {
  A = NaN,
  B = NaN,
}
const a: E.A = E.B; // TS2322 in tsgo, valid in TypeScript

TypeScript's JS Map treats NaN === NaN for key purposes, so this isn't an issue there.

Changes

  • getNumberLiteralType: Added a dedicated nanType *Type field to bypass the map[jsnum.Number]*Type lookup for NaN values
  • getEnumLiteralType: Added enumNaNLiteralTypes map[*ast.Symbol]*Type keyed by enum symbol, so NaN members within the same enum share a type while different enums remain distinct
  • Removes the enumConstantMembers.types.diff baseline (convergence with TypeScript)

Copilot AI and others added 2 commits May 16, 2026 20:19
Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/4d642ea9-d310-4a99-b4f0-21b5bbc1eb13

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
In Go, NaN != NaN for map key comparisons, causing each NaN-valued
enum member to get a distinct type. Fix by caching NaN types separately
from the map-based caches in both getNumberLiteralType and
getEnumLiteralType.

Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/4d642ea9-d310-4a99-b4f0-21b5bbc1eb13

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix distinct enum literal type error for NaN values Fix NaN-valued enum members creating distinct literal types May 16, 2026
Copilot AI requested a review from jakebailey May 16, 2026 20:34
Copy link
Copy Markdown
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this is what I expected the fix to be

@jakebailey jakebailey marked this pull request as ready for review May 16, 2026 20:40
Copilot AI review requested due to automatic review settings May 16, 2026 20:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Go-specific bug where NaN-valued enum members produced distinct literal types because Go map lookups always miss on NaN keys (IEEE 754 NaN != NaN). The fix routes NaN values through dedicated cache fields, ensuring NaN members within the same enum share a literal type (matching TypeScript's Map behavior which treats NaN keys as equal).

Changes:

  • Added dedicated nanType field to bypass map lookup for plain numeric NaN literals.
  • Added enumNaNLiteralTypes map[*ast.Symbol]*Type keyed by enum symbol so NaN enum members share a type per enum.
  • Added compiler test and removed obsolete enumConstantMembers.types.diff baseline (now converged with TypeScript).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
internal/checker/checker.go Add nanType and enumNaNLiteralTypes caches; special-case NaN in getNumberLiteralType and getEnumLiteralType.
testdata/tests/cases/compiler/enumNaNValues.ts New regression test covering NaN members within and across enums.
testdata/baselines/reference/compiler/enumNaNValues.* New baselines for the regression test.
testdata/baselines/reference/compiler/enumAutoIncrementValue.types Baseline update reflecting converged literal type identity.
testdata/baselines/reference/submodule/conformance/enumConstantMembers.types Submodule baseline now matches TS reference.
testdata/baselines/reference/submodule/conformance/enumConstantMembers.types.diff Removed (convergence with TypeScript).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tsgo creates a distinct enum literal type for each NaN-valued enum member

3 participants