Skip to content

Commit 90ae9ff

Browse files
author
Andy
authored
If there is an export default x; alias declaration, disallow other default exports (microsoft#19872)
1 parent a1014b2 commit 90ae9ff

7 files changed

+53
-5
lines changed

src/compiler/binder.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -2205,15 +2205,14 @@ namespace ts {
22052205
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
22062206
}
22072207
else {
2208-
// An export default clause with an expression exports a value
2209-
// We want to exclude both class and function here, this is necessary to issue an error when there are both
2210-
// default export-assignment and default export function and class declaration.
2211-
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node)
2208+
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
22122209
// An export default clause with an EntityNameExpression exports all meanings of that identifier
22132210
? SymbolFlags.Alias
22142211
// An export default clause with any other expression exports a value
22152212
: SymbolFlags.Property;
2216-
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
2213+
// If there is an `export default x;` alias declaration, can't `export default` anything else.
2214+
// (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
2215+
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All);
22172216
}
22182217
}
22192218

src/compiler/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3021,6 +3021,10 @@ namespace ts {
30213021
Optional = 1 << 24, // Optional property
30223022
Transient = 1 << 25, // Transient symbol (created during type check)
30233023

3024+
/* @internal */
3025+
All = FunctionScopedVariable | BlockScopedVariable | Property | EnumMember | Function | Class | Interface | ConstEnum | RegularEnum | ValueModule | NamespaceModule | TypeLiteral
3026+
| ObjectLiteral | Method | Constructor | GetAccessor | SetAccessor | Signature | TypeParameter | TypeAlias | ExportValue | Alias | Prototype | ExportStar | Optional | Transient,
3027+
30243028
Enum = RegularEnum | ConstEnum,
30253029
Variable = FunctionScopedVariable | BlockScopedVariable,
30263030
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(1,26): error TS2528: A module cannot have multiple default exports.
2+
tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(3,16): error TS2528: A module cannot have multiple default exports.
3+
4+
5+
==== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts (2 errors) ====
6+
export default interface A {}
7+
~
8+
!!! error TS2528: A module cannot have multiple default exports.
9+
interface B {}
10+
export default B;
11+
~
12+
!!! error TS2528: A module cannot have multiple default exports.
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//// [exportDefaultAlias_excludesEverything.ts]
2+
export default interface A {}
3+
interface B {}
4+
export default B;
5+
6+
7+
//// [exportDefaultAlias_excludesEverything.js]
8+
"use strict";
9+
exports.__esModule = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts ===
2+
export default interface A {}
3+
>A : Symbol(A, Decl(exportDefaultAlias_excludesEverything.ts, 0, 0))
4+
5+
interface B {}
6+
>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29))
7+
8+
export default B;
9+
>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29))
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts ===
2+
export default interface A {}
3+
>A : A
4+
5+
interface B {}
6+
>B : B
7+
8+
export default B;
9+
>B : B
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default interface A {}
2+
interface B {}
3+
export default B;

0 commit comments

Comments
 (0)