Skip to content

Stop alias deprecation walks at declaration-free targets - #65484

Open
Marc Rousavy (mrousavy) wants to merge 1 commit into
microsoft:mainfrom
mrousavy:fix/declaration-free-alias-deprecation
Open

Marc Rousavy (mrousavy) wants to merge 1 commit into
microsoft:mainfrom
mrousavy:fix/declaration-free-alias-deprecation

Conversation

@mrousavy

Copy link
Copy Markdown

The native checker hangs while checking a function that returns a namespace imported from a CommonJS module whose export is undefined.

// target.cjs
module.exports = undefined
// bridge.mjs
import * as ns from './target.cjs'; export function read() { return ns }
// main.ts
import { read } from './bridge.mjs'; read();

resolveAliasWithDeprecationCheck reaches a non-nil declaration-free intrinsic undefined symbol. Its declaration-bearing branch neither advances nor exits for this target. Require declarations before continuing that branch; the existing else terminates the walk and retains the resolved synthetic namespace target. Declared alias/deprecation behavior and both identity exits remain covered.

This changes one production function and adds three compiler fixtures, one declared-alias/deprecation/type-error control and six generated type/symbol baselines. The namespace baselines retain { default: undefined; }. The original cycle and an unused-namespace control are included alongside the reduction.

AI assistance was used to investigate and prepare this patch and its tests. No human personal-review or shepherding claim is made. This draft is offered for maintainer review or adaptation; the repository-wide gates below remain unrun.

Tested on exact main 056d69edb807d4cd4351059f084a7f191c6aea0f, Go1.27.4, Node24.21.0 and pinned npm11.21.1:

go -C ./tsc test -count=1 -run=TestLocal/aliasToDeclarationFreeUndefined -v ./internal/testrunner
go -C ./tsc test -count=1 -run=TestDeclaredAliasDeprecationAndTypeError -v ./internal/checker

All three maintained fixtures and 27 leaf checks pass with their six generated reference baselines. The declared control retains TS2322 and four deprecation suggestions. Scoped pinned dprint/gofumpt checks pass for the two Go files; testdata follows the repository's formatting exclusion.

Removing only the production guard makes the reduction and original cycle time out, with native stacks in the alias deprecation walk. Restoring it gives a fresh passing focused run. The unused control completes its checks. No timeout or oracle was relaxed for the candidate. Initial missing-baseline, assertion int/int32 and formatting failures were corrected before the final passing runs; the generated baselines were accepted through the normal harness task.

Remaining gates:

  • Associated issue and Backlog triage.
  • Whole-repository validation, lint, format and tidy.
  • Full test suite and distribution checks.
  • Contributor License Agreement handling.

No new published fixed package or broad language-server/API qualification is claimed.

@mrousavy

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@mrousavy
Marc Rousavy (mrousavy) marked this pull request as ready for review November 13, 2026 11:39
Copilot AI balanced review requested due to automatic review settings November 13, 2026 11:39
@typescript-automation

Copy link
Copy Markdown
Contributor

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are reported for the fix to the checker hang during CommonJS namespace resolution.

No open issues 🎉

What changed in this PR

Fixes a native TypeScript checker hang when resolving a namespace imported from a CommonJS module that exports undefined.

Changes:

  • Stops alias deprecation walks at declaration-free targets while preserving the resolved namespace.
  • Adds reduced, cyclic-import, and unused-namespace compiler fixtures with type and symbol baselines.
  • Adds a checker control test for declared-alias deprecation suggestions and TS2322 diagnostics.
File Description
tsc/​internal/​checker/​checker.go Terminates alias walks when the target has no declarations.
tsc/​internal/​checker/​alias_terminal_test.go Checks declared-alias deprecations and an assignment type error.
tsc/​testdata/​tests/​cases/​compiler/​aliasToDeclarationFreeUndefined.ts Adds the minimal hang regression.
tsc/​testdata/​tests/​cases/​compiler/​aliasToDeclarationFreeUndefinedCycle.ts Covers the original cyclic-import scenario.
tsc/​testdata/​tests/​cases/​compiler/​aliasToDeclarationFreeUndefinedUnused.ts Adds an unused-namespace control.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefined.types Records the reduced case’s namespace and return types.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefined.symbols Records symbol resolution for the reduced case.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefinedCycle.types Records inferred types across the import cycle.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefinedCycle.symbols Records symbol resolution across the import cycle.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefinedUnused.types Records types for the unused-namespace control.
tsc/​testdata/​baselines/​reference/​compiler/​aliasToDeclarationFreeUndefinedUnused.symbols Records symbols for the unused-namespace control.

Review effort: Balanced

This branch has not been deployed

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

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants