diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index ca3b6744b27..f8dc0339bb0 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -461,28 +461,32 @@ namespace ts.codefix { const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); if (defaultExport) return { symbol: defaultExport, kind: ImportKind.Default }; const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol); - return exportEquals === moduleSymbol ? undefined : { symbol: exportEquals, kind: getExportEqualsImportKind(importingFile, compilerOptions, checker) }; + return exportEquals === moduleSymbol ? undefined : { symbol: exportEquals, kind: getExportEqualsImportKind(importingFile, compilerOptions) }; } - function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, checker: TypeChecker): ImportKind { + function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions): ImportKind { + const allowSyntheticDefaults = getAllowSyntheticDefaultImports(compilerOptions); + // 1. 'import =' will not work in es2015+, so the decision is between a default + // and a namespace import, based on allowSyntheticDefaultImports/esModuleInterop. if (getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { - return getAllowSyntheticDefaultImports(compilerOptions) ? ImportKind.Default : ImportKind.Namespace; + return allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace; } + // 2. 'import =' will not work in JavaScript, so the decision is between a default + // and const/require. if (isInJSFile(importingFile)) { return isExternalModule(importingFile) ? ImportKind.Default : ImportKind.ConstEquals; } + // 3. At this point the most correct choice is probably 'import =', but people + // really hate that, so look to see if the importing file has any precedent + // on how to handle it. for (const statement of importingFile.statements) { if (isImportEqualsDeclaration(statement)) { return ImportKind.Equals; } - if (isImportDeclaration(statement) && statement.importClause && statement.importClause.name) { - const moduleSymbol = checker.getImmediateAliasedSymbol(statement.importClause.symbol); - if (moduleSymbol && moduleSymbol.name !== InternalSymbolName.Default) { - return ImportKind.Default; - } - } } - return ImportKind.Equals; + // 4. We have no precedent to go on, so just use a default import if + // allowSyntheticDefaultImports/esModuleInterop is enabled. + return allowSyntheticDefaults ? ImportKind.Default : ImportKind.Equals; } function getDefaultExportInfoWorker(defaultExport: Symbol, moduleSymbol: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions): { readonly symbolForMeaning: Symbol, readonly name: string } | undefined { diff --git a/tests/cases/fourslash/importNameCodeFixNewImportExportEqualsCommonJSInteropOn.ts b/tests/cases/fourslash/importNameCodeFixNewImportExportEqualsCommonJSInteropOn.ts index e8f223ca9f4..5c6ef12fcfd 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportExportEqualsCommonJSInteropOn.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportExportEqualsCommonJSInteropOn.ts @@ -18,7 +18,7 @@ ////} // @Filename: /a.ts -////import bar from "bar"; +////import bar = require("bar"); //// ////foo @@ -27,25 +27,27 @@ // @Filename: /c.ts ////import es from "es"; +////import bar = require("bar"); //// ////foo // 1. Should match existing imports of 'export =' goTo.file('/a.ts'); -verify.importFixAtPosition([`import bar from "bar"; -import foo from "foo"; +verify.importFixAtPosition([`import bar = require("bar"); +import foo = require("foo"); foo`]); -// 2. Should default to ImportEquals +// 2. Should default to default import goTo.file('/b.ts'); -verify.importFixAtPosition([`import foo = require("foo"); +verify.importFixAtPosition([`import foo from "foo"; foo`]); // 3. Importing an 'export default' doesn’t count toward the usage heursitic goTo.file('/c.ts'); verify.importFixAtPosition([`import es from "es"; +import bar = require("bar"); import foo = require("foo"); foo`]); \ No newline at end of file