Skip to content

fix(checker): reject exports originating from global augmentations - #64236

Closed
erantianantha wants to merge 1 commit into
microsoft:mainfrom
erantianantha:fix/reject-exports-from-global-augmentations
Closed

erantianantha wants to merge 1 commit into
microsoft:mainfrom
erantianantha:fix/reject-exports-from-global-augmentations

Conversation

@erantianantha

Copy link
Copy Markdown
Contributor

Fixes #64152.

Problem

When exporting bindings from a module without a local declaration (e.g. export { Math };), TypeScript correctly issues error TS2661 (Cannot export '{0}'. Only local declarations can be exported from a module.).

However, exports originating from a global scope augmentation (declare global { ... }) were previously permitted without error:

declare global {
    var XYZ: number;
}

export { XYZ }; // ❌ Permitted without error

Root Cause

In checkExportSpecifier (tsc/internal/checker/checker.go), the global declaration check only tested whether the declaration container was a global source file (ast.IsGlobalSourceFile(declarationContainer)). Declarations inside a global augmentation have an ast.ModuleBlock declaration container whose parent is a global scope augmentation (ast.IsGlobalScopeAugmentation(declarationContainer.Parent)), bypassing the error check.

Fix

Update checkExportSpecifier to treat declarations inside module blocks of global scope augmentations as non-local export sources:

isGlobalDeclaration := false
if symbol != nil && symbol.Declarations != nil {
	declarationContainer := ast.GetDeclarationContainer(symbol.Declarations[0])
	isGlobalDeclaration = ast.IsGlobalSourceFile(declarationContainer) || ast.IsModuleBlock(declarationContainer) && ast.IsGlobalScopeAugmentation(declarationContainer.Parent)
}

Add compiler test case exportSpecifierForAGlobalAugmentation.ts and reference baselines.

Fixes microsoft#64152.

When checking an export specifier without a module specifier (e.g. `export { XYZ }`),
the checker verifies that the resolved symbol is a local declaration rather than a global
declaration (reporting TS2661 "Cannot export '{0}'. Only local declarations can be exported from a module.").

Previously, only symbols declared in global source files (ast.IsGlobalSourceFile) were checked,
which created a hole for declarations originating inside `declare global { ... }` augmentations in
external modules.

Update the check to also recognize declarations within module blocks whose parent is a global
scope augmentation (`ast.IsModuleBlock(container) && ast.IsGlobalScopeAugmentation(container.Parent)`).

Add compiler test case: exportSpecifierForAGlobalAugmentation.ts
Copilot AI balanced review requested due to automatic review settings September 10, 2026 19:30
@github-project-automation github-project-automation Bot moved this to Not started in PR Backlog Sep 10, 2026
@typescript-automation typescript-automation Bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Sep 10, 2026

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

The focused checker change correctly addresses the reported hole and includes matching regression coverage.

Pull request overview

Fixes rejection of exports sourced from global augmentations.

Changes:

  • Detects declarations within global augmentation module blocks.
  • Adds a compiler regression test and reference baselines.
  • Includes an unrelated whitespace-only change.
File summaries
File Description
tsc/internal/checker/checker.go Rejects exports originating from global augmentations.
tsc/internal/checker/relater.go Adds a non-functional blank line.
tsc/testdata/tests/cases/compiler/exportSpecifierForAGlobalAugmentation.ts Adds the regression case.
tsc/testdata/baselines/reference/compiler/exportSpecifierForAGlobalAugmentation.errors.txt Captures expected TS2661.
tsc/testdata/baselines/reference/compiler/exportSpecifierForAGlobalAugmentation.js Captures emitted output.
tsc/testdata/baselines/reference/compiler/exportSpecifierForAGlobalAugmentation.symbols Captures symbol information.
tsc/testdata/baselines/reference/compiler/exportSpecifierForAGlobalAugmentation.types Captures inferred types.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@DanielRosenwasser

Copy link
Copy Markdown
Member

Sorry, there's already a PR out at #64162.

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

Status: Done

Development

Successfully merging this pull request may close these issues.

No error when exporting from global augmentations

3 participants