diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a3a2be8bca3..170364db3fe 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1602,7 +1602,7 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } - if (isExternalModuleAugmentation(node)) { + if (isModuleAugmentationExternal(node)) { declareModuleSymbol(node); } else { @@ -1618,10 +1618,7 @@ namespace ts { } const symbol = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - - if (pattern) { - (file.patternAmbientModules || (file.patternAmbientModules = [])).push({ pattern, symbol }); - } + file.patternAmbientModules = append(file.patternAmbientModules, pattern && { pattern, symbol }); } } else { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a43b9e7520..24eaf97cab0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23771,8 +23771,7 @@ namespace ts { // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module). const checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & SymbolFlags.Transient); if (checkBody && node.body) { - // body of ambient external module is always a module block - for (const statement of (node.body).statements) { + for (const statement of node.body.statements) { checkModuleAugmentationElement(statement, isGlobalAugmentation); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d8efd8d8af3..7d6e58ad9a4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2093,6 +2093,9 @@ namespace ts { export type ModuleBody = NamespaceBody | JSDocNamespaceBody; + /* @internal */ + export interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; } + export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer { kind: SyntaxKind.ModuleDeclaration; parent?: ModuleBody | SourceFile; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8108d0f1692..b6099c3959c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -424,9 +424,8 @@ namespace ts { return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause; } - export function isAmbientModule(node: Node): boolean { - return node && isModuleDeclaration(node) && - (node.name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node)); + export function isAmbientModule(node: Node): node is AmbientModuleDeclaration { + return isModuleDeclaration(node) && (node.name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node)); } export function isModuleWithStringLiteralName(node: Node): node is ModuleDeclaration { @@ -457,18 +456,19 @@ namespace ts { return !!(module.flags & NodeFlags.GlobalAugmentation); } - export function isExternalModuleAugmentation(node: Node): boolean { + export function isExternalModuleAugmentation(node: Node): node is AmbientModuleDeclaration { + return isAmbientModule(node) && isModuleAugmentationExternal(node); + } + + export function isModuleAugmentationExternal(node: AmbientModuleDeclaration) { // external module augmentation is a ambient module declaration that is either: // - defined in the top level scope and source file is an external module // - defined inside ambient module declaration located in the top level scope and source file not an external module - if (!node || !isAmbientModule(node)) { - return false; - } switch (node.parent.kind) { case SyntaxKind.SourceFile: - return isExternalModule(node.parent); + return isExternalModule(node.parent); case SyntaxKind.ModuleBlock: - return isAmbientModule(node.parent.parent) && !isExternalModule(node.parent.parent.parent); + return isAmbientModule(node.parent.parent) && isSourceFile(node.parent.parent.parent) && !isExternalModule(node.parent.parent.parent); } return false; } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 9f61b4ea69d..807506af24e 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -63,7 +63,7 @@ namespace ts.FindAllReferences { // Module augmentations may use this module's exports without importing it. for (const decl of exportingModuleSymbol.declarations) { if (isExternalModuleAugmentation(decl)) { - addIndirectUser(decl as SourceFileLike); + addIndirectUser(decl); } }