Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 9, 2026

Port of microsoft/TypeScript#61376.

Variables declared in for-in/for-of loops were incorrectly triggering TS2454 ("used before being assigned") when referenced in closures within the loop body.

for (let x of [1, 2]) {
  function f() {
    x;  // Error: Variable 'x' is used before being assigned (spurious)
  }
}

Changes

  • Add !ast.IsForInOrOfStatement(immediateDeclaration.Parent.Parent) check to isNeverInitialized in internal/checker/checker.go
  • Add local test unusedLocalsInForInOrOf1.ts from upstream PR with baselines

Variables in for-in/for-of loops are implicitly initialized by the loop iteration and should not be treated as uninitialized.

Original prompt

Port microsoft/TypeScript#61376

Custom agent used: Strada to Corsa Port Expert
A Go and TypeScript expert who can easily figure out how to port PRs from one language to another


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Port of microsoft/TypeScript#61376. Adds check for isForInOrOfStatement
to prevent false positive TS2454 errors for variables declared in
for-in/for-of loops when referenced in closures within the loop body.

Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Copilot AI changed the title [WIP] Port changes from TypeScript PR 61376 Port PR #61376: Fix spurious "used before being assigned" errors in for of/in loops Jan 9, 2026
Copilot AI requested a review from RyanCavanaugh January 9, 2026 18:56
Copy link
Member

@RyanCavanaugh RyanCavanaugh left a comment

Choose a reason for hiding this comment

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

Diff looks wonky because of the line breaks, what's actually happening is this

-isNeverInitialized := immediateDeclaration != nil && ast.IsVariableDeclaration(immediateDeclaration)                                                                  && immediateDeclaration.Initializer() == nil && immediateDeclaration.AsVariableDeclaration().ExclamationToken == nil && c.isMutableLocalVariableDeclaration(immediateDeclaration) && !c.isSymbolAssignedDefinitely(symbol)
+isNeverInitialized := immediateDeclaration != nil && ast.IsVariableDeclaration(immediateDeclaration) && !ast.IsForInOrOfStatement(immediateDeclaration.Parent.Parent) && immediateDeclaration.Initializer() == nil && immediateDeclaration.AsVariableDeclaration().ExclamationToken == nil && c.isMutableLocalVariableDeclaration(immediateDeclaration) && !c.isSymbolAssignedDefinitely(symbol)

@RyanCavanaugh RyanCavanaugh marked this pull request as ready for review January 9, 2026 19:01
Copilot AI review requested due to automatic review settings January 9, 2026 19:01
Copy link
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

This pull request ports TypeScript PR #61376, which fixes spurious "used before being assigned" errors (TS2454) for variables declared in for-in/for-of loops when they are referenced in closures within the loop body.

Key Changes:

  • Added a check !ast.IsForInOrOfStatement(immediateDeclaration.Parent.Parent) to the isNeverInitialized condition in checkIdentifier function
  • Variables in for-in/for-of loops are now correctly recognized as implicitly initialized by the loop iteration

Copy link
Member

@RyanCavanaugh RyanCavanaugh left a comment

Choose a reason for hiding this comment

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

@copilot also add the new tests from the upstream PR as local tests in this repo

Added test from upstream PR microsoft/TypeScript#61376 to verify the fix
for spurious "used before being assigned" errors (TS2454) in for-in/of loops.

Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 15, 2026

@copilot also add the new tests from the upstream PR as local tests in this repo

Added the test from upstream PR as a local test in testdata/tests/cases/compiler/unusedLocalsInForInOrOf1.ts with corresponding baselines in commit 9208fd4.

@RyanCavanaugh RyanCavanaugh added this pull request to the merge queue Jan 21, 2026
Merged via the queue into main with commit 4ec6989 Jan 21, 2026
22 checks passed
@RyanCavanaugh RyanCavanaugh deleted the copilot/port-typescript-pr-61376 branch January 21, 2026 19:57
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.

3 participants