diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ea8fb3eea8d15..774c35de77bbe 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -234,13 +234,17 @@ namespace ts { } if (symbolFlags & SymbolFlags.Value) { - const { valueDeclaration } = symbol; - if (!valueDeclaration || - (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || - (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) { - // other kinds of value declarations take precedence over modules and assignment declarations - symbol.valueDeclaration = node; - } + setValueDeclaration(symbol, node); + } + } + + function setValueDeclaration(symbol: Symbol, node: Declaration): void { + const { valueDeclaration } = symbol; + if (!valueDeclaration || + (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || + (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) { + // other kinds of value declarations take precedence over modules and assignment declarations + symbol.valueDeclaration = node; } } @@ -2286,14 +2290,19 @@ namespace ts { bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)!); } else { - const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) + const flags = exportAssignmentIsAlias(node) // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression; ? SymbolFlags.Alias // An export default clause with any other expression exports a value : SymbolFlags.Property; // If there is an `export default x;` alias declaration, can't `export default` anything else. // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.) - declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All); + const symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All); + + if (node.isExportEquals) { + // Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set. + setValueDeclaration(symbol, node); + } } } diff --git a/tests/baselines/reference/errorForConflictingExportEqualsValue.errors.txt b/tests/baselines/reference/errorForConflictingExportEqualsValue.errors.txt index 9a5858f46ab21..19ebd6ebb20d9 100644 --- a/tests/baselines/reference/errorForConflictingExportEqualsValue.errors.txt +++ b/tests/baselines/reference/errorForConflictingExportEqualsValue.errors.txt @@ -1,9 +1,10 @@ -tests/cases/compiler/errorForConflictingExportEqualsValue.ts(2,1): error TS2309: An export assignment cannot be used in a module with other exported elements. +/a.ts(2,1): error TS2309: An export assignment cannot be used in a module with other exported elements. -==== tests/cases/compiler/errorForConflictingExportEqualsValue.ts (1 errors) ==== +==== /a.ts (1 errors) ==== export var x; - export = {}; - ~~~~~~~~~~~~ + export = x; + ~~~~~~~~~~~ !!! error TS2309: An export assignment cannot be used in a module with other exported elements. + import("./a"); \ No newline at end of file diff --git a/tests/baselines/reference/errorForConflictingExportEqualsValue.js b/tests/baselines/reference/errorForConflictingExportEqualsValue.js index 88762e7e84675..65adec3590272 100644 --- a/tests/baselines/reference/errorForConflictingExportEqualsValue.js +++ b/tests/baselines/reference/errorForConflictingExportEqualsValue.js @@ -1,8 +1,10 @@ -//// [errorForConflictingExportEqualsValue.ts] +//// [a.ts] export var x; -export = {}; +export = x; +import("./a"); -//// [errorForConflictingExportEqualsValue.js] +//// [a.js] "use strict"; -module.exports = {}; +Promise.resolve().then(function () { return require("./a"); }); +module.exports = exports.x; diff --git a/tests/baselines/reference/errorForConflictingExportEqualsValue.symbols b/tests/baselines/reference/errorForConflictingExportEqualsValue.symbols index a66ef69c1cbbe..138f37f4a5e32 100644 --- a/tests/baselines/reference/errorForConflictingExportEqualsValue.symbols +++ b/tests/baselines/reference/errorForConflictingExportEqualsValue.symbols @@ -1,6 +1,10 @@ -=== tests/cases/compiler/errorForConflictingExportEqualsValue.ts === +=== /a.ts === export var x; ->x : Symbol(x, Decl(errorForConflictingExportEqualsValue.ts, 0, 10)) +>x : Symbol(x, Decl(a.ts, 0, 10)) -export = {}; +export = x; +>x : Symbol(x, Decl(a.ts, 0, 10)) + +import("./a"); +>"./a" : Symbol("/a", Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/errorForConflictingExportEqualsValue.types b/tests/baselines/reference/errorForConflictingExportEqualsValue.types index f2484e83d0d4b..b99151691203f 100644 --- a/tests/baselines/reference/errorForConflictingExportEqualsValue.types +++ b/tests/baselines/reference/errorForConflictingExportEqualsValue.types @@ -1,7 +1,11 @@ -=== tests/cases/compiler/errorForConflictingExportEqualsValue.ts === +=== /a.ts === export var x; >x : any -export = {}; ->{} : {} +export = x; +>x : any + +import("./a"); +>import("./a") : Promise +>"./a" : "./a" diff --git a/tests/cases/compiler/errorForConflictingExportEqualsValue.ts b/tests/cases/compiler/errorForConflictingExportEqualsValue.ts index 59af1f46690d5..a91ecc390b5a9 100644 --- a/tests/cases/compiler/errorForConflictingExportEqualsValue.ts +++ b/tests/cases/compiler/errorForConflictingExportEqualsValue.ts @@ -1,2 +1,5 @@ +// @lib: es6 +// @Filename: /a.ts export var x; -export = {}; +export = x; +import("./a");