From 98ec1e87306e8981ab2031150def01fdc4c25c82 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 26 Sep 2018 12:40:30 -0700 Subject: [PATCH] Fix commonjs export= merging (#27368) (#27371) I'm surprised we haven't seen more of this; I suspect it's because the mixed `module.exports=` + `export.foo=` pattern isn't that common. However, it'll happen any time that the exported symbol is unknown; getCommonJsExportEquals blithely clones unknownSymbol and proceeds to stick the `exports.foo=` properties onto it. This causes problems later, because the compiler checks for unknownSymbol with `===`. The fix is to not stick properties onto a clone of unknownSymbol. This makes the correct errors appear and removes the crash. --- src/compiler/checker.ts | 2 +- .../moduleExportAliasUnknown.errors.txt | 12 ++++++++++++ .../reference/moduleExportAliasUnknown.symbols | 11 +++++++++++ .../reference/moduleExportAliasUnknown.types | 17 +++++++++++++++++ .../salsa/moduleExportAliasUnknown.ts | 6 ++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/moduleExportAliasUnknown.errors.txt create mode 100644 tests/baselines/reference/moduleExportAliasUnknown.symbols create mode 100644 tests/baselines/reference/moduleExportAliasUnknown.types create mode 100644 tests/cases/conformance/salsa/moduleExportAliasUnknown.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a000bf1f7a7..a66a7edcf18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2344,7 +2344,7 @@ namespace ts { } function getCommonJsExportEquals(exported: Symbol | undefined, moduleSymbol: Symbol): Symbol | undefined { - if (!exported || moduleSymbol.exports!.size === 1) { + if (!exported || exported === unknownSymbol || moduleSymbol.exports!.size === 1) { return exported; } const merged = cloneSymbol(exported); diff --git a/tests/baselines/reference/moduleExportAliasUnknown.errors.txt b/tests/baselines/reference/moduleExportAliasUnknown.errors.txt new file mode 100644 index 00000000000..83d04dfefb7 --- /dev/null +++ b/tests/baselines/reference/moduleExportAliasUnknown.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/salsa/bug27025.js(1,25): error TS2339: Property 'nonprop' does not exist on type 'Window'. +tests/cases/conformance/salsa/bug27025.js(2,15): error TS2304: Cannot find name 'bar'. + + +==== tests/cases/conformance/salsa/bug27025.js (2 errors) ==== + module.exports = window.nonprop; + ~~~~~~~ +!!! error TS2339: Property 'nonprop' does not exist on type 'Window'. + exports.foo = bar; + ~~~ +!!! error TS2304: Cannot find name 'bar'. + \ No newline at end of file diff --git a/tests/baselines/reference/moduleExportAliasUnknown.symbols b/tests/baselines/reference/moduleExportAliasUnknown.symbols new file mode 100644 index 00000000000..2913a704e10 --- /dev/null +++ b/tests/baselines/reference/moduleExportAliasUnknown.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/salsa/bug27025.js === +module.exports = window.nonprop; +>module.exports : Symbol("tests/cases/conformance/salsa/bug27025", Decl(bug27025.js, 0, 0)) +>module : Symbol(export=, Decl(bug27025.js, 0, 0)) +>exports : Symbol(export=, Decl(bug27025.js, 0, 0)) +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) + +exports.foo = bar; +>exports : Symbol(foo, Decl(bug27025.js, 0, 32)) +>foo : Symbol(foo, Decl(bug27025.js, 0, 32)) + diff --git a/tests/baselines/reference/moduleExportAliasUnknown.types b/tests/baselines/reference/moduleExportAliasUnknown.types new file mode 100644 index 00000000000..60fae1456d1 --- /dev/null +++ b/tests/baselines/reference/moduleExportAliasUnknown.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/bug27025.js === +module.exports = window.nonprop; +>module.exports = window.nonprop : any +>module.exports : any +>module : { "tests/cases/conformance/salsa/bug27025": any; } +>exports : any +>window.nonprop : any +>window : Window +>nonprop : any + +exports.foo = bar; +>exports.foo = bar : any +>exports.foo : any +>exports : any +>foo : any +>bar : any + diff --git a/tests/cases/conformance/salsa/moduleExportAliasUnknown.ts b/tests/cases/conformance/salsa/moduleExportAliasUnknown.ts new file mode 100644 index 00000000000..f2fdb384e61 --- /dev/null +++ b/tests/cases/conformance/salsa/moduleExportAliasUnknown.ts @@ -0,0 +1,6 @@ +// @allowJs: true +// @noEmit: true +// @checkJs: true +// @Filename: bug27025.js +module.exports = window.nonprop; +exports.foo = bar;