diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index a2ed0feb795a7..f871dca8993ff 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -134,6 +134,7 @@ import { isFunctionLikeDeclaration, isIdentifier, isIdentifierPart, + isImportDeclaration, isImportMeta, isImportOrExportSpecifier, isImportSpecifier, @@ -1012,7 +1013,27 @@ export namespace Core { const checker = program.getTypeChecker(); // constructors should use the class symbol, detected by name, if present - const symbol = checker.getSymbolAtLocation(isConstructorDeclaration(node) && node.parent.name || node); + let symbol = checker.getSymbolAtLocation(isConstructorDeclaration(node) && node.parent.name || node); + + // Handle export = namespace case where ES6 import cannot resolve the symbol + if (!symbol && isIdentifier(node) && isImportSpecifier(node.parent)) { + const spec = node.parent; + // Get the imported name: for 'import { foo as bar }', use 'foo'; for 'import { foo }', use 'foo' + const importedName = spec.propertyName && isIdentifier(spec.propertyName) + ? spec.propertyName.escapedText + : spec.name.escapedText; + const importDecl = findAncestor(spec, isImportDeclaration); + const moduleSymbol = importDecl?.moduleSpecifier ? checker.getSymbolAtLocation(importDecl.moduleSpecifier) : undefined; + if (moduleSymbol) { + // Fall back to module exports when direct symbol resolution fails + // Handles export= namespace members for ES6 import specifiers + const moduleExports = checker.getExportsOfModule(moduleSymbol); + const exportedSymbol = find(moduleExports, s => s.escapedName === importedName); + if (exportedSymbol) { + symbol = exportedSymbol; + } + } + } // Could not find a symbol e.g. unknown identifier if (!symbol) { diff --git a/tests/cases/fourslash/findAllReferencesExportEqualsNamespace.ts b/tests/cases/fourslash/findAllReferencesExportEqualsNamespace.ts new file mode 100644 index 0000000000000..d57ccbd7dc1d2 --- /dev/null +++ b/tests/cases/fourslash/findAllReferencesExportEqualsNamespace.ts @@ -0,0 +1,16 @@ +/// + +// @module: commonjs + +// @Filename: /mod.d.ts +////export = React; +//// +////declare namespace React { +//// function /*1*/lazy(): void; +////} + +// @Filename: /index.ts +////import { /*2*/lazy } from "./mod" +/////*3*/lazy(); + +verify.baselineFindAllReferences("1", "2", "3"); \ No newline at end of file