diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2341a0f7dfd..8c1e401912d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18763,7 +18763,13 @@ namespace ts { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } if (file.symbol && file.symbol.globalExports) { - mergeSymbolTable(globals, file.symbol.globalExports); + // Merge in UMD exports with first-in-wins semantics (see #9771) + const source = file.symbol.globalExports; + for (const id in source) { + if (!(id in globals)) { + globals[id] = source[id]; + } + } } }); diff --git a/tests/baselines/reference/umdGlobalConflict.js b/tests/baselines/reference/umdGlobalConflict.js new file mode 100644 index 00000000000..e8a820e2333 --- /dev/null +++ b/tests/baselines/reference/umdGlobalConflict.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/umdGlobalConflict.ts] //// + +//// [index.d.ts] +export as namespace Alpha; +export var x: string; + +//// [index.d.ts] +export as namespace Alpha; +export var y: number; + +//// [consumer.ts] +import * as v1 from './v1'; +import * as v2 from './v2'; + +//// [global.ts] +// Should be OK, first in wins +const p: string = Alpha.x; + +//// [consumer.js] +"use strict"; +//// [global.js] +// Should be OK, first in wins +var p = Alpha.x; diff --git a/tests/baselines/reference/umdGlobalConflict.symbols b/tests/baselines/reference/umdGlobalConflict.symbols new file mode 100644 index 00000000000..b13fb0f25b1 --- /dev/null +++ b/tests/baselines/reference/umdGlobalConflict.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/v1/index.d.ts === +export as namespace Alpha; +>Alpha : Symbol(Alpha, Decl(index.d.ts, 0, 0)) + +export var x: string; +>x : Symbol(x, Decl(index.d.ts, 1, 10)) + +=== tests/cases/compiler/v2/index.d.ts === +export as namespace Alpha; +>Alpha : Symbol(Alpha, Decl(index.d.ts, 0, 0)) + +export var y: number; +>y : Symbol(y, Decl(index.d.ts, 1, 10)) + +=== tests/cases/compiler/consumer.ts === +import * as v1 from './v1'; +>v1 : Symbol(v1, Decl(consumer.ts, 0, 6)) + +import * as v2 from './v2'; +>v2 : Symbol(v2, Decl(consumer.ts, 1, 6)) + +=== tests/cases/compiler/global.ts === +// Should be OK, first in wins +const p: string = Alpha.x; +>p : Symbol(p, Decl(global.ts, 1, 5)) +>Alpha.x : Symbol(Alpha.x, Decl(index.d.ts, 1, 10)) +>Alpha : Symbol(Alpha, Decl(index.d.ts, 0, 0)) +>x : Symbol(Alpha.x, Decl(index.d.ts, 1, 10)) + diff --git a/tests/baselines/reference/umdGlobalConflict.types b/tests/baselines/reference/umdGlobalConflict.types new file mode 100644 index 00000000000..fa74e26874f --- /dev/null +++ b/tests/baselines/reference/umdGlobalConflict.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/v1/index.d.ts === +export as namespace Alpha; +>Alpha : typeof Alpha + +export var x: string; +>x : string + +=== tests/cases/compiler/v2/index.d.ts === +export as namespace Alpha; +>Alpha : typeof + +export var y: number; +>y : number + +=== tests/cases/compiler/consumer.ts === +import * as v1 from './v1'; +>v1 : typeof v1 + +import * as v2 from './v2'; +>v2 : typeof v2 + +=== tests/cases/compiler/global.ts === +// Should be OK, first in wins +const p: string = Alpha.x; +>p : string +>Alpha.x : string +>Alpha : typeof Alpha +>x : string + diff --git a/tests/cases/compiler/umdGlobalConflict.ts b/tests/cases/compiler/umdGlobalConflict.ts new file mode 100644 index 00000000000..58b4ea6be02 --- /dev/null +++ b/tests/cases/compiler/umdGlobalConflict.ts @@ -0,0 +1,15 @@ +//@filename: v1/index.d.ts +export as namespace Alpha; +export var x: string; + +//@filename: v2/index.d.ts +export as namespace Alpha; +export var y: number; + +//@filename: consumer.ts +import * as v1 from './v1'; +import * as v2 from './v2'; + +//@filename: global.ts +// Should be OK, first in wins +const p: string = Alpha.x; \ No newline at end of file