Skip to content

Commit 9e0d8c3

Browse files
authored
Create import helpers for named imports if they contain default imports (#21550) (#21561)
1 parent 2916c9c commit 9e0d8c3

File tree

5 files changed

+152
-2
lines changed

5 files changed

+152
-2
lines changed

src/compiler/transformers/module/module.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,36 @@ namespace ts {
690690
return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
691691
}
692692

693+
function getNamedImportCount(node: ImportDeclaration) {
694+
if (!(node.importClause && node.importClause.namedBindings)) return 0;
695+
const names = node.importClause.namedBindings;
696+
if (!names) return 0;
697+
if (!isNamedImports(names)) return 0;
698+
return names.elements.length;
699+
}
700+
701+
function containsDefaultReference(node: NamedImportBindings) {
702+
if (!node) return false;
703+
if (!isNamedImports(node)) return false;
704+
return some(node.elements, isNamedDefaultReference);
705+
}
706+
707+
function isNamedDefaultReference(e: ImportSpecifier) {
708+
return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default;
709+
}
693710

694711
function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) {
695712
if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) {
696713
return innerExpr;
697714
}
698-
if (getNamespaceDeclarationNode(node)) {
715+
const nameCount = getNamedImportCount(node);
716+
const hasDefault = nameCount > 0 ? containsDefaultReference(node.importClause.namedBindings) : undefined;
717+
718+
if (getNamespaceDeclarationNode(node) || (nameCount > 1 && hasDefault)) {
699719
context.requestEmitHelper(importStarHelper);
700720
return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
701721
}
702-
if (isDefaultImport(node)) {
722+
if (isDefaultImport(node) || (nameCount === 1 && hasDefault)) {
703723
context.requestEmitHelper(importDefaultHelper);
704724
return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
705725
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//// [tests/cases/compiler/esModuleInteropNamedDefaultImports.ts] ////
2+
3+
//// [mod.ts]
4+
export default class Foo {}
5+
export class Bar {}
6+
//// [idx.ts]
7+
import Foo from "./mod";
8+
import { default as Foo2 } from "./mod";
9+
import { Bar, default as Foo3 } from "./mod";
10+
new Foo();
11+
new Foo2();
12+
new Bar();
13+
new Foo3();
14+
15+
//// [mod.js]
16+
"use strict";
17+
exports.__esModule = true;
18+
var Foo = /** @class */ (function () {
19+
function Foo() {
20+
}
21+
return Foo;
22+
}());
23+
exports["default"] = Foo;
24+
var Bar = /** @class */ (function () {
25+
function Bar() {
26+
}
27+
return Bar;
28+
}());
29+
exports.Bar = Bar;
30+
//// [idx.js]
31+
"use strict";
32+
var __importDefault = (this && this.__importDefault) || function (mod) {
33+
return (mod && mod.__esModule) ? mod : { "default": mod };
34+
}
35+
var __importStar = (this && this.__importStar) || function (mod) {
36+
if (mod && mod.__esModule) return mod;
37+
var result = {};
38+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
39+
result["default"] = mod;
40+
return result;
41+
}
42+
exports.__esModule = true;
43+
var mod_1 = __importDefault(require("./mod"));
44+
var mod_2 = __importDefault(require("./mod"));
45+
var mod_3 = __importStar(require("./mod"));
46+
new mod_1["default"]();
47+
new mod_2["default"]();
48+
new mod_3.Bar();
49+
new mod_3["default"]();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/mod.ts ===
2+
export default class Foo {}
3+
>Foo : Symbol(Foo, Decl(mod.ts, 0, 0))
4+
5+
export class Bar {}
6+
>Bar : Symbol(Bar, Decl(mod.ts, 0, 27))
7+
8+
=== tests/cases/compiler/idx.ts ===
9+
import Foo from "./mod";
10+
>Foo : Symbol(Foo, Decl(idx.ts, 0, 6))
11+
12+
import { default as Foo2 } from "./mod";
13+
>default : Symbol(Foo2, Decl(idx.ts, 1, 8))
14+
>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8))
15+
16+
import { Bar, default as Foo3 } from "./mod";
17+
>Bar : Symbol(Bar, Decl(idx.ts, 2, 8))
18+
>default : Symbol(Foo3, Decl(idx.ts, 2, 13))
19+
>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13))
20+
21+
new Foo();
22+
>Foo : Symbol(Foo, Decl(idx.ts, 0, 6))
23+
24+
new Foo2();
25+
>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8))
26+
27+
new Bar();
28+
>Bar : Symbol(Bar, Decl(idx.ts, 2, 8))
29+
30+
new Foo3();
31+
>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13))
32+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/mod.ts ===
2+
export default class Foo {}
3+
>Foo : Foo
4+
5+
export class Bar {}
6+
>Bar : Bar
7+
8+
=== tests/cases/compiler/idx.ts ===
9+
import Foo from "./mod";
10+
>Foo : typeof Foo
11+
12+
import { default as Foo2 } from "./mod";
13+
>default : typeof Foo
14+
>Foo2 : typeof Foo
15+
16+
import { Bar, default as Foo3 } from "./mod";
17+
>Bar : typeof Bar
18+
>default : typeof Foo
19+
>Foo3 : typeof Foo
20+
21+
new Foo();
22+
>new Foo() : Foo
23+
>Foo : typeof Foo
24+
25+
new Foo2();
26+
>new Foo2() : Foo
27+
>Foo2 : typeof Foo
28+
29+
new Bar();
30+
>new Bar() : Bar
31+
>Bar : typeof Bar
32+
33+
new Foo3();
34+
>new Foo3() : Foo
35+
>Foo3 : typeof Foo
36+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @module: commonjs
2+
// @esModuleInterop: true
3+
// @filename: mod.ts
4+
export default class Foo {}
5+
export class Bar {}
6+
// @filename: idx.ts
7+
import Foo from "./mod";
8+
import { default as Foo2 } from "./mod";
9+
import { Bar, default as Foo3 } from "./mod";
10+
new Foo();
11+
new Foo2();
12+
new Bar();
13+
new Foo3();

0 commit comments

Comments
 (0)