diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8791706396e..32aafcd700e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -306,7 +306,7 @@ namespace ts { } function getDisplayName(node: Declaration): string { - return isNamedDeclaration(node) ? declarationNameToString(node.name) : unescapeLeadingUnderscores(getDeclarationName(node)!); // TODO: GH#18217 + return isNamedDeclaration(node) ? declarationNameToString(node.name) : unescapeLeadingUnderscores(Debug.assertDefined(getDeclarationName(node))); } /** @@ -383,9 +383,11 @@ namespace ts { let message = symbol.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; + let messageNeedsName = true; if (symbol.flags & SymbolFlags.Enum || includes & SymbolFlags.Enum) { message = Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations; + messageNeedsName = false; } if (symbol.declarations && symbol.declarations.length) { @@ -394,6 +396,7 @@ namespace ts { // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set. if (isDefaultExport) { message = Diagnostics.A_module_cannot_have_multiple_default_exports; + messageNeedsName = false; } else { // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration. @@ -403,14 +406,16 @@ namespace ts { if (symbol.declarations && symbol.declarations.length && (node.kind === SyntaxKind.ExportAssignment && !(node).isExportEquals)) { message = Diagnostics.A_module_cannot_have_multiple_default_exports; + messageNeedsName = false; } } } - forEach(symbol.declarations, declaration => { - file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(declaration) || declaration, message, getDisplayName(declaration))); - }); - file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(node) || node, message, getDisplayName(node))); + const addError = (decl: Declaration): void => { + file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(decl) || decl, message, messageNeedsName ? getDisplayName(decl) : undefined)); + }; + forEach(symbol.declarations, addError); + addError(node); symbol = createSymbol(SymbolFlags.None, name); } diff --git a/tests/baselines/reference/duplicateDefaultExport.errors.txt b/tests/baselines/reference/duplicateDefaultExport.errors.txt new file mode 100644 index 00000000000..e35e416ff6b --- /dev/null +++ b/tests/baselines/reference/duplicateDefaultExport.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/duplicateDefaultExport.ts(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/duplicateDefaultExport.ts(2,1): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/compiler/duplicateDefaultExport.ts (2 errors) ==== + export default 0; + ~~~~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. + export default function() {} + ~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. + \ No newline at end of file diff --git a/tests/baselines/reference/duplicateDefaultExport.js b/tests/baselines/reference/duplicateDefaultExport.js new file mode 100644 index 00000000000..af0994bb833 --- /dev/null +++ b/tests/baselines/reference/duplicateDefaultExport.js @@ -0,0 +1,11 @@ +//// [duplicateDefaultExport.ts] +export default 0; +export default function() {} + + +//// [duplicateDefaultExport.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +function default_1() { } +exports["default"] = default_1; diff --git a/tests/baselines/reference/duplicateDefaultExport.symbols b/tests/baselines/reference/duplicateDefaultExport.symbols new file mode 100644 index 00000000000..6f978e28e78 --- /dev/null +++ b/tests/baselines/reference/duplicateDefaultExport.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/duplicateDefaultExport.ts === +export default 0; +No type information for this code.export default function() {} +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/duplicateDefaultExport.types b/tests/baselines/reference/duplicateDefaultExport.types new file mode 100644 index 00000000000..6f978e28e78 --- /dev/null +++ b/tests/baselines/reference/duplicateDefaultExport.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/duplicateDefaultExport.ts === +export default 0; +No type information for this code.export default function() {} +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/cases/compiler/duplicateDefaultExport.ts b/tests/cases/compiler/duplicateDefaultExport.ts new file mode 100644 index 00000000000..ead4a42facb --- /dev/null +++ b/tests/cases/compiler/duplicateDefaultExport.ts @@ -0,0 +1,2 @@ +export default 0; +export default function() {}