diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf1cc33d159..fcfee1b4684 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -212,6 +212,7 @@ namespace ts { return node ? isOptionalParameter(node) : false; }, tryGetMemberInModuleExports: (name, symbol) => tryGetMemberInModuleExports(escapeLeadingUnderscores(name), symbol), + tryGetMemberInModuleExportsAndProperties: (name, symbol) => tryGetMemberInModuleExportsAndProperties(escapeLeadingUnderscores(name), symbol), tryFindAmbientModuleWithoutAugmentations: moduleName => { // we deliberately exclude augmentations // since we are only interested in declarations of the module itself @@ -1776,6 +1777,17 @@ namespace ts { } } + function tryGetMemberInModuleExportsAndProperties(memberName: __String, moduleSymbol: Symbol): Symbol | undefined { + const symbol = tryGetMemberInModuleExports(memberName, moduleSymbol); + if (!symbol) { + const exportEquals = resolveExternalModuleSymbol(moduleSymbol); + if (exportEquals !== moduleSymbol) { + return getPropertyOfType(getTypeOfSymbol(exportEquals), memberName); + } + } + return symbol; + } + function getExportsOfSymbol(symbol: Symbol): SymbolTable { return symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e52c9fb9f5a..09f1b5cfcc5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2581,6 +2581,8 @@ namespace ts { getAmbientModules(): Symbol[]; tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined; + /** Unlike `tryGetMemberInModuleExports`, this includes properties of an `export =` value. */ + /* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined; getApparentType(type: Type): Type; getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined; getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index f94daab7e70..ac477d49455 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -178,8 +178,11 @@ namespace ts.codefix { } } + // "default" is a keyword and not a legal identifier for the import, so we don't expect it here + Debug.assert(name !== "default"); + // check exports with the same name - const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExports(name, moduleSymbol); + const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(name, moduleSymbol); if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) { const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name)); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFile5.ts b/tests/cases/fourslash/importNameCodeFixNewImportFile5.ts new file mode 100644 index 00000000000..28cf48d8a5f --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportFile5.ts @@ -0,0 +1,16 @@ +/// + +//// [|bar/*0*/();|] + +// @Filename: foo.ts +//// interface MyStatic { +//// bar(): void; +//// } +//// declare var x: MyStatic; +//// export = x; + +verify.importFixAtPosition([ +`import { bar } from "./foo"; + +bar();` +]); \ No newline at end of file