Skip to content

Commit ae2f006

Browse files
committed
Fix default import/export helper usage
1 parent 5c5f180 commit ae2f006

File tree

46 files changed

+1039
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1039
-35
lines changed

src/compiler/checker.ts

+15
Original file line numberDiff line numberDiff line change
@@ -35268,6 +35268,12 @@ namespace ts {
3526835268
checkCollisionWithRequireExportsInGeneratedCode(node, node.name!);
3526935269
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name!);
3527035270
checkAliasSymbol(node);
35271+
if (node.kind === SyntaxKind.ImportSpecifier &&
35272+
idText(node.propertyName || node.name) === "default" &&
35273+
compilerOptions.esModuleInterop &&
35274+
moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) {
35275+
checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault);
35276+
}
3527135277
}
3527235278

3527335279
function checkImportDeclaration(node: ImportDeclaration) {
@@ -35461,6 +35467,14 @@ namespace ts {
3546135467
}
3546235468
}
3546335469
}
35470+
else {
35471+
if (compilerOptions.esModuleInterop &&
35472+
moduleKind !== ModuleKind.System &&
35473+
moduleKind < ModuleKind.ES2015 &&
35474+
idText(node.propertyName || node.name) === "default") {
35475+
checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault);
35476+
}
35477+
}
3546435478
}
3546535479

3546635480
function checkExportAssignment(node: ExportAssignment) {
@@ -37646,6 +37660,7 @@ namespace ts {
3764637660
case ExternalEmitHelpers.AsyncValues: return "__asyncValues";
3764737661
case ExternalEmitHelpers.ExportStar: return "__exportStar";
3764837662
case ExternalEmitHelpers.ImportStar: return "__importStar";
37663+
case ExternalEmitHelpers.ImportDefault: return "__importDefault";
3764937664
case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject";
3765037665
case ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet";
3765137666
case ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet";

src/compiler/factory/emitHelpers.ts

+26
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace ts {
3131
createImportStarHelper(expression: Expression): Expression;
3232
createImportStarCallbackHelper(): Expression;
3333
createImportDefaultHelper(expression: Expression): Expression;
34+
createExportStarHelper(moduleExpression: Expression, exportsExpression?: Expression): Expression;
3435
// Class Fields Helpers
3536
createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier): Expression;
3637
createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression): Expression;
@@ -69,6 +70,7 @@ namespace ts {
6970
createImportStarHelper,
7071
createImportStarCallbackHelper,
7172
createImportDefaultHelper,
73+
createExportStarHelper,
7274
// Class Fields Helpers
7375
createClassPrivateFieldGetHelper,
7476
createClassPrivateFieldSetHelper,
@@ -366,6 +368,16 @@ namespace ts {
366368
);
367369
}
368370

371+
function createExportStarHelper(moduleExpression: Expression, exportsExpression: Expression = factory.createIdentifier("exports")) {
372+
context.requestEmitHelper(exportStarHelper);
373+
context.requestEmitHelper(createBindingHelper);
374+
return factory.createCallExpression(
375+
getUnscopedHelperName("__exportStar"),
376+
/*typeArguments*/ undefined,
377+
[moduleExpression, exportsExpression]
378+
);
379+
}
380+
369381
// Class Fields Helpers
370382

371383
function createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier) {
@@ -815,6 +827,19 @@ namespace ts {
815827
};`
816828
};
817829

830+
// emit output for the __export helper function
831+
export const exportStarHelper: UnscopedEmitHelper = {
832+
name: "typescript:export-star",
833+
importName: "__exportStar",
834+
scoped: false,
835+
dependencies: [createBindingHelper],
836+
priority: 2,
837+
text: `
838+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
839+
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
840+
};`
841+
};
842+
818843
// Class fields helpers
819844
export const classPrivateFieldGetHelper: UnscopedEmitHelper = {
820845
name: "typescript:classPrivateFieldGet",
@@ -864,6 +889,7 @@ namespace ts {
864889
generatorHelper,
865890
importStarHelper,
866891
importDefaultHelper,
892+
exportStarHelper,
867893
classPrivateFieldGetHelper,
868894
classPrivateFieldSetHelper,
869895
createBindingHelper,

src/compiler/transformers/module/module.ts

+9-29
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,6 @@ namespace ts {
700700

701701
const promise = factory.createNewExpression(factory.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
702702
if (compilerOptions.esModuleInterop) {
703-
context.requestEmitHelper(importStarHelper);
704703
return factory.createCallExpression(factory.createPropertyAccessExpression(promise, factory.createIdentifier("then")), /*typeArguments*/ undefined, [emitHelpers().createImportStarCallbackHelper()]);
705704
}
706705
return promise;
@@ -715,7 +714,6 @@ namespace ts {
715714
const promiseResolveCall = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
716715
let requireCall: Expression = factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
717716
if (compilerOptions.esModuleInterop) {
718-
context.requestEmitHelper(importStarHelper);
719717
requireCall = emitHelpers().createImportStarHelper(requireCall);
720718
}
721719

@@ -755,8 +753,7 @@ namespace ts {
755753
return innerExpr;
756754
}
757755
if (getExportNeedsImportStarHelper(node)) {
758-
context.requestEmitHelper(importStarHelper);
759-
return factory.createCallExpression(context.getEmitHelperFactory().getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
756+
return emitHelpers().createImportStarHelper(innerExpr);
760757
}
761758
return innerExpr;
762759
}
@@ -766,11 +763,9 @@ namespace ts {
766763
return innerExpr;
767764
}
768765
if (getImportNeedsImportStarHelper(node)) {
769-
context.requestEmitHelper(importStarHelper);
770766
return emitHelpers().createImportStarHelper(innerExpr);
771767
}
772768
if (getImportNeedsImportDefaultHelper(node)) {
773-
context.requestEmitHelper(importDefaultHelper);
774769
return emitHelpers().createImportDefaultHelper(innerExpr);
775770
}
776771
return innerExpr;
@@ -1015,18 +1010,21 @@ namespace ts {
10151010
setOriginalNode(
10161011
setTextRange(
10171012
factory.createExpressionStatement(
1018-
context.getEmitHelperFactory().createCreateBindingHelper(generatedName, factory.createStringLiteralFromNode(specifier.propertyName || specifier.name), specifier.propertyName ? factory.createStringLiteralFromNode(specifier.name) : undefined)
1013+
emitHelpers().createCreateBindingHelper(generatedName, factory.createStringLiteralFromNode(specifier.propertyName || specifier.name), specifier.propertyName ? factory.createStringLiteralFromNode(specifier.name) : undefined)
10191014
),
10201015
specifier),
10211016
specifier
10221017
)
10231018
);
10241019
}
10251020
else {
1021+
const exportNeedsImportDefault =
1022+
!!compilerOptions.esModuleInterop &&
1023+
!(getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) &&
1024+
idText(specifier.propertyName || specifier.name) === "default";
10261025
const exportedValue = factory.createPropertyAccessExpression(
1027-
generatedName,
1028-
specifier.propertyName || specifier.name
1029-
);
1026+
exportNeedsImportDefault ? emitHelpers().createImportDefaultHelper(generatedName) : generatedName,
1027+
specifier.propertyName || specifier.name);
10301028
statements.push(
10311029
setOriginalNode(
10321030
setTextRange(
@@ -1069,7 +1067,7 @@ namespace ts {
10691067
return setOriginalNode(
10701068
setTextRange(
10711069
factory.createExpressionStatement(
1072-
createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName)
1070+
emitHelpers().createExportStarHelper(moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName)
10731071
),
10741072
node),
10751073
node
@@ -1857,24 +1855,6 @@ namespace ts {
18571855
}
18581856
}
18591857

1860-
// emit output for the __export helper function
1861-
const exportStarHelper: UnscopedEmitHelper = {
1862-
name: "typescript:export-star",
1863-
importName: "__exportStar",
1864-
scoped: false,
1865-
dependencies: [createBindingHelper],
1866-
priority: 2,
1867-
text: `
1868-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
1869-
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
1870-
};`
1871-
};
1872-
1873-
function createExportStarHelper(context: TransformationContext, module: Expression) {
1874-
context.requestEmitHelper(exportStarHelper);
1875-
return context.factory.createCallExpression(context.getEmitHelperFactory().getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, context.factory.createIdentifier("exports")]);
1876-
}
1877-
18781858
// emit helper for dynamic import
18791859
const dynamicImportUMDHelper: EmitHelper = {
18801860
name: "typescript:dynamicimport-sync-require",

src/compiler/types.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -6415,10 +6415,11 @@ namespace ts {
64156415
AsyncValues = 1 << 15, // __asyncValues (used by ES2017 for..await..of transformation)
64166416
ExportStar = 1 << 16, // __exportStar (used by CommonJS/AMD/UMD module transformation)
64176417
ImportStar = 1 << 17, // __importStar (used by CommonJS/AMD/UMD module transformation)
6418-
MakeTemplateObject = 1 << 18, // __makeTemplateObject (used for constructing template string array objects)
6419-
ClassPrivateFieldGet = 1 << 19, // __classPrivateFieldGet (used by the class private field transformation)
6420-
ClassPrivateFieldSet = 1 << 20, // __classPrivateFieldSet (used by the class private field transformation)
6421-
CreateBinding = 1 << 21, // __createBinding (use by the module transform for (re)exports and namespace imports)
6418+
ImportDefault = 1 << 18, // __importStar (used by CommonJS/AMD/UMD module transformation)
6419+
MakeTemplateObject = 1 << 19, // __makeTemplateObject (used for constructing template string array objects)
6420+
ClassPrivateFieldGet = 1 << 20, // __classPrivateFieldGet (used by the class private field transformation)
6421+
ClassPrivateFieldSet = 1 << 21, // __classPrivateFieldSet (used by the class private field transformation)
6422+
CreateBinding = 1 << 22, // __createBinding (use by the module transform for (re)exports and namespace imports)
64226423
FirstEmitHelper = Extends,
64236424
LastEmitHelper = CreateBinding,
64246425

tests/baselines/reference/exportAsNamespace_missingEmitHelpers.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ exports.__esModule = true;
1414
"use strict";
1515
exports.__esModule = true;
1616
exports.ns = void 0;
17-
exports.ns = require("./a"); // Error
17+
var tslib_1 = require("tslib");
18+
exports.ns = tslib_1.__importStar(require("./a")); // Error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [tests/cases/compiler/importHelpersWithImportOrExportDefault.ts] ////
2+
3+
//// [a.ts]
4+
export default class { }
5+
6+
//// [b.ts]
7+
export { default } from "./a";
8+
export { default as a } from "./a";
9+
import { default as b } from "./a";
10+
void b;
11+
12+
//// [tslib.d.ts]
13+
declare module "tslib" {
14+
function __importDefault(m: any): void;
15+
}
16+
17+
//// [a.js]
18+
define(["require", "exports"], function (require, exports) {
19+
"use strict";
20+
Object.defineProperty(exports, "__esModule", { value: true });
21+
class default_1 {
22+
}
23+
exports.default = default_1;
24+
});
25+
//// [b.js]
26+
define(["require", "exports", "./a", "./a", "./a"], function (require, exports, a_1, a_2, a_3) {
27+
"use strict";
28+
Object.defineProperty(exports, "__esModule", { value: true });
29+
exports.a = exports.default = void 0;
30+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return a_1.default; } });
31+
Object.defineProperty(exports, "a", { enumerable: true, get: function () { return a_2.default; } });
32+
void a_3.default;
33+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/a.ts ===
2+
export default class { }
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/compiler/b.ts ===
5+
export { default } from "./a";
6+
>default : Symbol(default, Decl(b.ts, 0, 8))
7+
8+
export { default as a } from "./a";
9+
>default : Symbol(b, Decl(a.ts, 0, 0))
10+
>a : Symbol(a, Decl(b.ts, 1, 8))
11+
12+
import { default as b } from "./a";
13+
>default : Symbol(b, Decl(a.ts, 0, 0))
14+
>b : Symbol(b, Decl(b.ts, 2, 8))
15+
16+
void b;
17+
>b : Symbol(b, Decl(b.ts, 2, 8))
18+
19+
=== tests/cases/compiler/tslib.d.ts ===
20+
declare module "tslib" {
21+
>"tslib" : Symbol("tslib", Decl(tslib.d.ts, --, --))
22+
23+
function __importDefault(m: any): void;
24+
>__importDefault : Symbol(__importDefault, Decl(tslib.d.ts, --, --))
25+
>m : Symbol(m, Decl(tslib.d.ts, --, --))
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/a.ts ===
2+
export default class { }
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/compiler/b.ts ===
5+
export { default } from "./a";
6+
>default : typeof b
7+
8+
export { default as a } from "./a";
9+
>default : typeof b
10+
>a : typeof b
11+
12+
import { default as b } from "./a";
13+
>default : typeof b
14+
>b : typeof b
15+
16+
void b;
17+
>void b : undefined
18+
>b : typeof b
19+
20+
=== tests/cases/compiler/tslib.d.ts ===
21+
declare module "tslib" {
22+
>"tslib" : typeof import("tslib")
23+
24+
function __importDefault(m: any): void;
25+
>__importDefault : (m: any) => void
26+
>m : any
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/compiler/importHelpersWithImportOrExportDefault.ts] ////
2+
3+
//// [a.ts]
4+
export default class { }
5+
6+
//// [b.ts]
7+
export { default } from "./a";
8+
export { default as a } from "./a";
9+
import { default as b } from "./a";
10+
void b;
11+
12+
//// [tslib.d.ts]
13+
declare module "tslib" {
14+
function __importDefault(m: any): void;
15+
}
16+
17+
//// [a.js]
18+
"use strict";
19+
Object.defineProperty(exports, "__esModule", { value: true });
20+
class default_1 {
21+
}
22+
exports.default = default_1;
23+
//// [b.js]
24+
"use strict";
25+
Object.defineProperty(exports, "__esModule", { value: true });
26+
exports.a = exports.default = void 0;
27+
var a_1 = require("./a");
28+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return a_1.default; } });
29+
var a_2 = require("./a");
30+
Object.defineProperty(exports, "a", { enumerable: true, get: function () { return a_2.default; } });
31+
const a_3 = require("./a");
32+
void a_3.default;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/a.ts ===
2+
export default class { }
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/compiler/b.ts ===
5+
export { default } from "./a";
6+
>default : Symbol(default, Decl(b.ts, 0, 8))
7+
8+
export { default as a } from "./a";
9+
>default : Symbol(b, Decl(a.ts, 0, 0))
10+
>a : Symbol(a, Decl(b.ts, 1, 8))
11+
12+
import { default as b } from "./a";
13+
>default : Symbol(b, Decl(a.ts, 0, 0))
14+
>b : Symbol(b, Decl(b.ts, 2, 8))
15+
16+
void b;
17+
>b : Symbol(b, Decl(b.ts, 2, 8))
18+
19+
=== tests/cases/compiler/tslib.d.ts ===
20+
declare module "tslib" {
21+
>"tslib" : Symbol("tslib", Decl(tslib.d.ts, --, --))
22+
23+
function __importDefault(m: any): void;
24+
>__importDefault : Symbol(__importDefault, Decl(tslib.d.ts, --, --))
25+
>m : Symbol(m, Decl(tslib.d.ts, --, --))
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/a.ts ===
2+
export default class { }
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/compiler/b.ts ===
5+
export { default } from "./a";
6+
>default : typeof b
7+
8+
export { default as a } from "./a";
9+
>default : typeof b
10+
>a : typeof b
11+
12+
import { default as b } from "./a";
13+
>default : typeof b
14+
>b : typeof b
15+
16+
void b;
17+
>void b : undefined
18+
>b : typeof b
19+
20+
=== tests/cases/compiler/tslib.d.ts ===
21+
declare module "tslib" {
22+
>"tslib" : typeof import("tslib")
23+
24+
function __importDefault(m: any): void;
25+
>__importDefault : (m: any) => void
26+
>m : any
27+
}

0 commit comments

Comments
 (0)