Skip to content

Stack overflow narrowing as const object assigned to loop variable it references #64012

Description

🔎 Search Terms

getTypeAtFlowLoopLabel, stack overflow loop narrowing, as const stack overflow, getAssignmentReducedType

🕗 Version & Regression Information

⏯ Playground Link

No response

💻 Code

type Candidate = { mode: "a"; output: unknown } | { mode: "b" };

export function run(): never {
  let lastCandidate: Candidate | null = null;
  while (true) {
    const candidate: Candidate = {
      mode: "a",
      output: lastCandidate,
    } as const;
    lastCandidate = candidate;
  }
}

🙁 Actual behavior

tsc crashes every time:

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

getTypeAtFlowLoopLabel (flow.go:1325)
getTypeAtFlowNode (flow.go:174)
getTypeAtFlowCondition (flow.go:355)
getFlowTypeOfReferenceEx (flow.go:98)
checkIdentifier (checker.go:11267)
... ~3.2M frames elided

🙂 Expected behavior

Compiles clean (it does on 5.9.3 and on nightlies up to 20260723)

Additional information about the issue

All three parts are needed to crash:

  • the annotation has to be a union (single object type is fine)
  • the object has to be as const (removing it is the workaround)
  • the object has to reference the loop variable it's assigned back to

Metadata

Metadata

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions