Skip to content

Commit 12b436b

Browse files
Merge pull request #5084 from MartyIX/patch-4
Compiler gives unhelpful error messages in the presence of multiple default exports
2 parents 543cce5 + 69ff6f5 commit 12b436b

13 files changed

+154
-7
lines changed

src/compiler/binder.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ namespace ts {
185185
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
186186
Debug.assert(!hasDynamicName(node));
187187

188+
let isDefaultExport = node.flags & NodeFlags.Default;
188189
// The exported symbol for an export default function/class node is always named "default"
189-
let name = node.flags & NodeFlags.Default && parent ? "default" : getDeclarationName(node);
190+
let name = isDefaultExport && parent ? "default" : getDeclarationName(node);
190191

191192
let symbol: Symbol;
192193
if (name !== undefined) {
@@ -227,6 +228,13 @@ namespace ts {
227228
let message = symbol.flags & SymbolFlags.BlockScopedVariable
228229
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
229230
: Diagnostics.Duplicate_identifier_0;
231+
232+
forEach(symbol.declarations, declaration => {
233+
if (declaration.flags & NodeFlags.Default) {
234+
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
235+
}
236+
});
237+
230238
forEach(symbol.declarations, declaration => {
231239
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
232240
});

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,10 @@
16561656
"category": "Error",
16571657
"code": 2527
16581658
},
1659+
"A module cannot have multiple default exports.": {
1660+
"category": "Error",
1661+
"code": 2528
1662+
},
16591663
"JSX element attributes type '{0}' must be an object type.": {
16601664
"category": "Error",
16611665
"code": 2600
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [defaultExportWithOverloads01.ts]
2+
3+
export default function f();
4+
export default function f(x: string);
5+
export default function f(...args: any[]) {
6+
}
7+
8+
//// [defaultExportWithOverloads01.js]
9+
function f() {
10+
var args = [];
11+
for (var _i = 0; _i < arguments.length; _i++) {
12+
args[_i - 0] = arguments[_i];
13+
}
14+
}
15+
Object.defineProperty(exports, "__esModule", { value: true });
16+
exports.default = f;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/conformance/es6/modules/defaultExportWithOverloads01.ts ===
2+
3+
export default function f();
4+
>f : Symbol(f, Decl(defaultExportWithOverloads01.ts, 0, 0), Decl(defaultExportWithOverloads01.ts, 1, 28), Decl(defaultExportWithOverloads01.ts, 2, 37))
5+
6+
export default function f(x: string);
7+
>f : Symbol(f, Decl(defaultExportWithOverloads01.ts, 0, 0), Decl(defaultExportWithOverloads01.ts, 1, 28), Decl(defaultExportWithOverloads01.ts, 2, 37))
8+
>x : Symbol(x, Decl(defaultExportWithOverloads01.ts, 2, 26))
9+
10+
export default function f(...args: any[]) {
11+
>f : Symbol(f, Decl(defaultExportWithOverloads01.ts, 0, 0), Decl(defaultExportWithOverloads01.ts, 1, 28), Decl(defaultExportWithOverloads01.ts, 2, 37))
12+
>args : Symbol(args, Decl(defaultExportWithOverloads01.ts, 3, 26))
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/conformance/es6/modules/defaultExportWithOverloads01.ts ===
2+
3+
export default function f();
4+
>f : { (): any; (x: string): any; }
5+
6+
export default function f(x: string);
7+
>f : { (): any; (x: string): any; }
8+
>x : string
9+
10+
export default function f(...args: any[]) {
11+
>f : { (): any; (x: string): any; }
12+
>args : any[]
13+
}

tests/baselines/reference/multipleDefaultExports01.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2300: Duplicate identifier 'foo'.
2-
tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2300: Duplicate identifier 'bar'.
3-
tests/cases/conformance/es6/modules/m1.ts(11,1): error TS2300: Duplicate identifier 'default'.
1+
tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2528: A module cannot have multiple default exports.
2+
tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2528: A module cannot have multiple default exports.
3+
tests/cases/conformance/es6/modules/m1.ts(11,1): error TS2528: A module cannot have multiple default exports.
44
tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof foo' is not callable. Did you mean to include 'new'?
55

66

77
==== tests/cases/conformance/es6/modules/m1.ts (3 errors) ====
88

99
export default class foo {
1010
~~~
11-
!!! error TS2300: Duplicate identifier 'foo'.
11+
!!! error TS2528: A module cannot have multiple default exports.
1212

1313
}
1414

1515
export default function bar() {
1616
~~~
17-
!!! error TS2300: Duplicate identifier 'bar'.
17+
!!! error TS2528: A module cannot have multiple default exports.
1818

1919
}
2020

2121
var x = 10;
2222
export default x;
2323
~~~~~~~~~~~~~~~~~
24-
!!! error TS2300: Duplicate identifier 'default'.
24+
!!! error TS2528: A module cannot have multiple default exports.
2525

2626
==== tests/cases/conformance/es6/modules/m2.ts (1 errors) ====
2727
import Entity from "./m1"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/conformance/es6/modules/multipleDefaultExports03.ts(2,22): error TS2528: A module cannot have multiple default exports.
2+
tests/cases/conformance/es6/modules/multipleDefaultExports03.ts(5,22): error TS2528: A module cannot have multiple default exports.
3+
4+
5+
==== tests/cases/conformance/es6/modules/multipleDefaultExports03.ts (2 errors) ====
6+
7+
export default class C {
8+
~
9+
!!! error TS2528: A module cannot have multiple default exports.
10+
}
11+
12+
export default class C {
13+
~
14+
!!! error TS2528: A module cannot have multiple default exports.
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [multipleDefaultExports03.ts]
2+
3+
export default class C {
4+
}
5+
6+
export default class C {
7+
}
8+
9+
//// [multipleDefaultExports03.js]
10+
var C = (function () {
11+
function C() {
12+
}
13+
return C;
14+
})();
15+
Object.defineProperty(exports, "__esModule", { value: true });
16+
exports.default = C;
17+
var C = (function () {
18+
function C() {
19+
}
20+
return C;
21+
})();
22+
Object.defineProperty(exports, "__esModule", { value: true });
23+
exports.default = C;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(2,25): error TS2393: Duplicate function implementation.
2+
tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(5,25): error TS2393: Duplicate function implementation.
3+
4+
5+
==== tests/cases/conformance/es6/modules/multipleDefaultExports04.ts (2 errors) ====
6+
7+
export default function f() {
8+
~
9+
!!! error TS2393: Duplicate function implementation.
10+
}
11+
12+
export default function f() {
13+
~
14+
!!! error TS2393: Duplicate function implementation.
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [multipleDefaultExports04.ts]
2+
3+
export default function f() {
4+
}
5+
6+
export default function f() {
7+
}
8+
9+
//// [multipleDefaultExports04.js]
10+
function f() {
11+
}
12+
Object.defineProperty(exports, "__esModule", { value: true });
13+
exports.default = f;
14+
function f() {
15+
}
16+
Object.defineProperty(exports, "__esModule", { value: true });
17+
exports.default = f;

0 commit comments

Comments
 (0)