diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab057d430a4..d829795439b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15055,11 +15055,20 @@ namespace ts { continue; } const { declarations, flags } = exports[id]; - // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) - if (!(flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) && (flags & SymbolFlags.TypeAlias ? declarations.length - 1 : declarations.length) > 1) { - const exportedDeclarations: Declaration[] = filter(declarations, isNotOverload); - if (exportedDeclarations.length > 1) { - for (const declaration of exportedDeclarations) { + // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. + // (TS Exceptions: namespaces, function overloads, enums, and interfaces) + if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) { + continue; + } + const exportedDeclarationsCount = countWhere(declarations, isNotOverload); + if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { + // it is legal to merge type alias with other values + // so count should be either 1 (just type alias) or 2 (type alias + merged value) + continue; + } + if (exportedDeclarationsCount > 1) { + for (const declaration of declarations) { + if (isNotOverload(declaration)) { diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, id)); } } diff --git a/tests/baselines/reference/exportRedeclarationTypeAliases.js b/tests/baselines/reference/exportRedeclarationTypeAliases.js new file mode 100644 index 00000000000..b1e2e200634 --- /dev/null +++ b/tests/baselines/reference/exportRedeclarationTypeAliases.js @@ -0,0 +1,9 @@ +//// [exportRedeclarationTypeAliases.ts] +export type Foo = number; +export function Foo(): number; +export function Foo(): any {} + +//// [exportRedeclarationTypeAliases.js] +"use strict"; +function Foo() { } +exports.Foo = Foo; diff --git a/tests/baselines/reference/exportRedeclarationTypeAliases.symbols b/tests/baselines/reference/exportRedeclarationTypeAliases.symbols new file mode 100644 index 00000000000..6561692e307 --- /dev/null +++ b/tests/baselines/reference/exportRedeclarationTypeAliases.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/exportRedeclarationTypeAliases.ts === +export type Foo = number; +>Foo : Symbol(Foo, Decl(exportRedeclarationTypeAliases.ts, 0, 0), Decl(exportRedeclarationTypeAliases.ts, 0, 25), Decl(exportRedeclarationTypeAliases.ts, 1, 30)) + +export function Foo(): number; +>Foo : Symbol(Foo, Decl(exportRedeclarationTypeAliases.ts, 0, 0), Decl(exportRedeclarationTypeAliases.ts, 0, 25), Decl(exportRedeclarationTypeAliases.ts, 1, 30)) + +export function Foo(): any {} +>Foo : Symbol(Foo, Decl(exportRedeclarationTypeAliases.ts, 0, 0), Decl(exportRedeclarationTypeAliases.ts, 0, 25), Decl(exportRedeclarationTypeAliases.ts, 1, 30)) + diff --git a/tests/baselines/reference/exportRedeclarationTypeAliases.types b/tests/baselines/reference/exportRedeclarationTypeAliases.types new file mode 100644 index 00000000000..f5c987373b6 --- /dev/null +++ b/tests/baselines/reference/exportRedeclarationTypeAliases.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/exportRedeclarationTypeAliases.ts === +export type Foo = number; +>Foo : number + +export function Foo(): number; +>Foo : () => number + +export function Foo(): any {} +>Foo : () => number + diff --git a/tests/cases/compiler/exportRedeclarationTypeAliases.ts b/tests/cases/compiler/exportRedeclarationTypeAliases.ts new file mode 100644 index 00000000000..eb5cbcd4c6d --- /dev/null +++ b/tests/cases/compiler/exportRedeclarationTypeAliases.ts @@ -0,0 +1,4 @@ +// @module: commonjs +export type Foo = number; +export function Foo(): number; +export function Foo(): any {} \ No newline at end of file