diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3e5c85149d1..10127bbfec1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2308,12 +2308,16 @@ namespace ts { if (isExportsOrModuleExportsOrAlias(file, e) || (isIdentifier(e) && e.escapedText === "module" && original === undefined)) { return file.symbol; } - Debug.assert(!!original); + if (!original) { + return undefined; + } const s = getJSInitializerSymbol(original); addDeclarationToSymbol(s, id, SymbolFlags.Module | SymbolFlags.JSContainer); return s; }); - declareSymbol(symbol.exports, symbol, lhs, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); + if (symbol) { + declareSymbol(symbol.exports, symbol, lhs, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); + } } function bindModuleExportsAssignment(node: BinaryExpression) { diff --git a/tests/baselines/reference/exportNestedNamespaces2.errors.txt b/tests/baselines/reference/exportNestedNamespaces2.errors.txt new file mode 100644 index 00000000000..f8378e27776 --- /dev/null +++ b/tests/baselines/reference/exportNestedNamespaces2.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/salsa/first.js(1,1): error TS2539: Cannot assign to '"tests/cases/conformance/salsa/first"' because it is not a variable. +tests/cases/conformance/salsa/first.js(1,11): error TS2304: Cannot find name 'require'. +tests/cases/conformance/salsa/first.js(2,9): error TS2339: Property 'formatters' does not exist on type 'typeof "tests/cases/conformance/salsa/first"'. +tests/cases/conformance/salsa/second.js(1,1): error TS2539: Cannot assign to '"tests/cases/conformance/salsa/second"' because it is not a variable. +tests/cases/conformance/salsa/second.js(1,11): error TS2304: Cannot find name 'require'. +tests/cases/conformance/salsa/second.js(2,9): error TS2339: Property 'formatters' does not exist on type 'typeof "tests/cases/conformance/salsa/second"'. + + +==== tests/cases/conformance/salsa/mod.js (0 errors) ==== + // Based on a pattern from adonis + exports.formatters = {} +==== tests/cases/conformance/salsa/first.js (3 errors) ==== + exports = require('./mod') + ~~~~~~~ +!!! error TS2539: Cannot assign to '"tests/cases/conformance/salsa/first"' because it is not a variable. + ~~~~~~~ +!!! error TS2304: Cannot find name 'require'. + exports.formatters.j = function (v) { + ~~~~~~~~~~ +!!! error TS2339: Property 'formatters' does not exist on type 'typeof "tests/cases/conformance/salsa/first"'. + return v + } +==== tests/cases/conformance/salsa/second.js (3 errors) ==== + exports = require('./mod') + ~~~~~~~ +!!! error TS2539: Cannot assign to '"tests/cases/conformance/salsa/second"' because it is not a variable. + ~~~~~~~ +!!! error TS2304: Cannot find name 'require'. + exports.formatters.o = function (v) { + ~~~~~~~~~~ +!!! error TS2339: Property 'formatters' does not exist on type 'typeof "tests/cases/conformance/salsa/second"'. + return v + } + +==== tests/cases/conformance/salsa/use.js (0 errors) ==== + import * as debug from './mod' + + debug.formatters.j + var one = debug.formatters.o(1) + \ No newline at end of file diff --git a/tests/baselines/reference/exportNestedNamespaces2.symbols b/tests/baselines/reference/exportNestedNamespaces2.symbols new file mode 100644 index 00000000000..bc14f9f8889 --- /dev/null +++ b/tests/baselines/reference/exportNestedNamespaces2.symbols @@ -0,0 +1,47 @@ +=== tests/cases/conformance/salsa/mod.js === +// Based on a pattern from adonis +exports.formatters = {} +>exports.formatters : Symbol(formatters, Decl(mod.js, 0, 0)) +>exports : Symbol(formatters, Decl(mod.js, 0, 0)) +>formatters : Symbol(formatters, Decl(mod.js, 0, 0)) + +=== tests/cases/conformance/salsa/first.js === +exports = require('./mod') +>exports : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0)) +>'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0)) + +exports.formatters.j = function (v) { +>exports : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0)) +>v : Symbol(v, Decl(first.js, 1, 33)) + + return v +>v : Symbol(v, Decl(first.js, 1, 33)) +} +=== tests/cases/conformance/salsa/second.js === +exports = require('./mod') +>exports : Symbol("tests/cases/conformance/salsa/second", Decl(second.js, 0, 0)) +>'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0)) + +exports.formatters.o = function (v) { +>exports : Symbol("tests/cases/conformance/salsa/second", Decl(second.js, 0, 0)) +>v : Symbol(v, Decl(second.js, 1, 33)) + + return v +>v : Symbol(v, Decl(second.js, 1, 33)) +} + +=== tests/cases/conformance/salsa/use.js === +import * as debug from './mod' +>debug : Symbol(debug, Decl(use.js, 0, 6)) + +debug.formatters.j +>debug.formatters : Symbol(debug.formatters, Decl(mod.js, 0, 0)) +>debug : Symbol(debug, Decl(use.js, 0, 6)) +>formatters : Symbol(debug.formatters, Decl(mod.js, 0, 0)) + +var one = debug.formatters.o(1) +>one : Symbol(one, Decl(use.js, 3, 3)) +>debug.formatters : Symbol(debug.formatters, Decl(mod.js, 0, 0)) +>debug : Symbol(debug, Decl(use.js, 0, 6)) +>formatters : Symbol(debug.formatters, Decl(mod.js, 0, 0)) + diff --git a/tests/baselines/reference/exportNestedNamespaces2.types b/tests/baselines/reference/exportNestedNamespaces2.types new file mode 100644 index 00000000000..761c9bc604e --- /dev/null +++ b/tests/baselines/reference/exportNestedNamespaces2.types @@ -0,0 +1,73 @@ +=== tests/cases/conformance/salsa/mod.js === +// Based on a pattern from adonis +exports.formatters = {} +>exports.formatters = {} : { [x: string]: any; } +>exports.formatters : { [x: string]: any; } +>exports : typeof "tests/cases/conformance/salsa/mod" +>formatters : { [x: string]: any; } +>{} : { [x: string]: any; } + +=== tests/cases/conformance/salsa/first.js === +exports = require('./mod') +>exports = require('./mod') : typeof "tests/cases/conformance/salsa/mod" +>exports : any +>require('./mod') : typeof "tests/cases/conformance/salsa/mod" +>require : any +>'./mod' : "./mod" + +exports.formatters.j = function (v) { +>exports.formatters.j = function (v) { return v} : (v: any) => any +>exports.formatters.j : any +>exports.formatters : any +>exports : typeof "tests/cases/conformance/salsa/first" +>formatters : any +>j : any +>function (v) { return v} : (v: any) => any +>v : any + + return v +>v : any +} +=== tests/cases/conformance/salsa/second.js === +exports = require('./mod') +>exports = require('./mod') : typeof "tests/cases/conformance/salsa/mod" +>exports : any +>require('./mod') : typeof "tests/cases/conformance/salsa/mod" +>require : any +>'./mod' : "./mod" + +exports.formatters.o = function (v) { +>exports.formatters.o = function (v) { return v} : (v: any) => any +>exports.formatters.o : any +>exports.formatters : any +>exports : typeof "tests/cases/conformance/salsa/second" +>formatters : any +>o : any +>function (v) { return v} : (v: any) => any +>v : any + + return v +>v : any +} + +=== tests/cases/conformance/salsa/use.js === +import * as debug from './mod' +>debug : typeof debug + +debug.formatters.j +>debug.formatters.j : any +>debug.formatters : { [x: string]: any; } +>debug : typeof debug +>formatters : { [x: string]: any; } +>j : any + +var one = debug.formatters.o(1) +>one : any +>debug.formatters.o(1) : any +>debug.formatters.o : any +>debug.formatters : { [x: string]: any; } +>debug : typeof debug +>formatters : { [x: string]: any; } +>o : any +>1 : 1 + diff --git a/tests/cases/conformance/salsa/exportNestedNamespaces2.ts b/tests/cases/conformance/salsa/exportNestedNamespaces2.ts new file mode 100644 index 00000000000..3745d3bd2c4 --- /dev/null +++ b/tests/cases/conformance/salsa/exportNestedNamespaces2.ts @@ -0,0 +1,23 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @Filename: mod.js +// Based on a pattern from adonis +exports.formatters = {} +// @Filename: first.js +exports = require('./mod') +exports.formatters.j = function (v) { + return v +} +// @Filename: second.js +exports = require('./mod') +exports.formatters.o = function (v) { + return v +} + +// @Filename: use.js +import * as debug from './mod' + +debug.formatters.j +var one = debug.formatters.o(1)