Skip to content

Commit b2b54cb

Browse files
aluanhaddadmhegazy
authored andcommitted
Import fix add import require support (#19802)
* import fix: suggest import..require where supported if synthetic defaults are unavailable * Add tests for import..require fix when targeting CommonJS, AMD, and UMD modules * fix failing tests
1 parent bd2e975 commit b2b54cb

9 files changed

+92
-6
lines changed

src/services/codefixes/importFixes.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ namespace ts.codefix {
180180
export const enum ImportKind {
181181
Named,
182182
Default,
183-
Namespace
183+
Namespace,
184+
Equals
184185
}
185186

186187
export function getCodeActionForImport(moduleSymbol: Symbol, context: ImportCodeFixOptions): ImportCodeAction[] {
@@ -252,11 +253,17 @@ namespace ts.codefix {
252253

253254
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier);
254255
const quotedModuleSpecifier = createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes);
255-
const importDecl = createImportDeclaration(
256+
const importDecl = kind !== ImportKind.Equals
257+
? createImportDeclaration(
256258
/*decorators*/ undefined,
257259
/*modifiers*/ undefined,
258-
createImportClauseOfKind(kind, symbolName),
259-
quotedModuleSpecifier);
260+
createImportClauseOfKind(kind, symbolName),
261+
quotedModuleSpecifier)
262+
: createImportEqualsDeclaration(
263+
/*decorators*/ undefined,
264+
/*modifiers*/ undefined,
265+
createIdentifier(symbolName),
266+
createExternalModuleReference(quotedModuleSpecifier));
260267

261268
const changes = ChangeTracker.with(context, changeTracker => {
262269
if (lastImportDeclaration) {
@@ -267,8 +274,10 @@ namespace ts.codefix {
267274
}
268275
});
269276

270-
const actionFormat = kind === ImportKind.Namespace
271-
? Diagnostics.Import_Asterisk_as_0_from_1
277+
const actionFormat = kind === ImportKind.Equals
278+
? Diagnostics.Import_0_require_1
279+
: kind === ImportKind.Namespace
280+
? Diagnostics.Import_Asterisk_as_0_from_1
272281
: Diagnostics.Import_0_from_1;
273282

274283
// if this file doesn't have any import statements, insert an import statement and then insert a new line
@@ -601,6 +610,9 @@ namespace ts.codefix {
601610
return namedBindings ? undefined : ChangeTracker.with(context, t =>
602611
t.replaceNode(sourceFile, importClause, createImportClause(name, createNamespaceImport(createIdentifier(symbolName)))));
603612

613+
case ImportKind.Equals:
614+
return undefined;
615+
604616
default:
605617
Debug.assertNever(kind);
606618
}
@@ -659,6 +671,12 @@ namespace ts.codefix {
659671
if (allowSyntheticDefaultImports) {
660672
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Default });
661673
}
674+
const moduleKind = getEmitModuleKind(compilerOptions);
675+
676+
// When a synthetic `default` is unavailable, use `import..require` if the module kind supports it.
677+
if (moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.CommonJS || moduleKind === ModuleKind.UMD) {
678+
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Equals });
679+
}
662680

663681
// Fall back to the `import * as ns` style import.
664682
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Namespace });

tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// <reference path="fourslash.ts" />
22
// @AllowSyntheticDefaultImports: false
3+
// @Module: system
34

45
// @Filename: a/f1.ts
56
//// [|export var x = 0;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts" />
2+
// @AllowSyntheticDefaultImports: false
3+
// @Module: commonjs
4+
5+
// @Filename: a/f1.ts
6+
//// [|export var x = 0;
7+
//// bar/*0*/();|]
8+
9+
// @Filename: a/foo.d.ts
10+
//// declare function bar(): number;
11+
//// export = bar;
12+
//// export as namespace bar;
13+
14+
verify.importFixAtPosition([
15+
`import bar = require("./foo");
16+
17+
export var x = 0;
18+
bar();`
19+
]);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts" />
2+
// @AllowSyntheticDefaultImports: false
3+
// @Module: amd
4+
5+
// @Filename: a/f1.ts
6+
//// [|export var x = 0;
7+
//// bar/*0*/();|]
8+
9+
// @Filename: a/foo.d.ts
10+
//// declare function bar(): number;
11+
//// export = bar;
12+
//// export as namespace bar;
13+
14+
verify.importFixAtPosition([
15+
`import bar = require("./foo");
16+
17+
export var x = 0;
18+
bar();`
19+
]);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts" />
2+
// @AllowSyntheticDefaultImports: false
3+
// @Module: umd
4+
5+
// @Filename: a/f1.ts
6+
//// [|export var x = 0;
7+
//// bar/*0*/();|]
8+
9+
// @Filename: a/foo.d.ts
10+
//// declare function bar(): number;
11+
//// export = bar;
12+
//// export as namespace bar;
13+
14+
verify.importFixAtPosition([
15+
`import bar = require("./foo");
16+
17+
export var x = 0;
18+
bar();`
19+
]);

tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/// <reference path="fourslash.ts" />
22

3+
// @AllowSyntheticDefaultImports: false
4+
// @Module: es2015
5+
36
// @Filename: a/f1.ts
47
//// [|export function test() { };
58
//// bar1/*0*/.bar;|]

tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/// <reference path="fourslash.ts" />
22

3+
// @AllowSyntheticDefaultImports: false
4+
// @Module: esnext
5+
36
// @Filename: a/f1.ts
47
//// [|import { bar } from "./foo";
58
////

tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/// <reference path="fourslash.ts" />
22

33
// @jsx: react
4+
// @allowSyntheticDefaultImports: false
5+
// @module: es2015
46

57
// @Filename: /node_modules/@types/react/index.d.ts
68
////export = React;

tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/// <reference path="fourslash.ts" />
22

33
// @jsx: react
4+
// @allowSyntheticDefaultImports: false
5+
// @module: es2015
46

57
// @Filename: /node_modules/@types/react/index.d.ts
68
////export = React;

0 commit comments

Comments
 (0)