From 9fb6acf1e1cdc768cdf6598d04dc3024c45d16f8 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 10 Nov 2020 11:28:49 -0800 Subject: [PATCH] Add missed resolveSymbol in commonjs import resolution (#41479) Fixes resolution of export aliases in the postfix-property-access case of commonjs require: ```js const { x } = require('./foo').nested x ``` This program would previously fail if `x` was an export alias. Fixes #41422 --- src/compiler/checker.ts | 2 +- .../reference/commonJSReexport.symbols | 41 ++++++++++++++++ .../reference/commonJSReexport.types | 49 +++++++++++++++++++ .../conformance/salsa/commonJSReexport.ts | 19 +++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/commonJSReexport.symbols create mode 100644 tests/baselines/reference/commonJSReexport.types create mode 100644 tests/cases/conformance/salsa/commonJSReexport.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9a71a6a0277e8..74a48de2be46e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2790,7 +2790,7 @@ namespace ts { const resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); const name = node.propertyName || node.name; if (commonJSPropertyAccess && resolved && isIdentifier(name)) { - return getPropertyOfType(getTypeOfSymbol(resolved), name.escapedText); + return resolveSymbol(getPropertyOfType(getTypeOfSymbol(resolved), name.escapedText), dontResolveAlias); } markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false); return resolved; diff --git a/tests/baselines/reference/commonJSReexport.symbols b/tests/baselines/reference/commonJSReexport.symbols new file mode 100644 index 0000000000000..7b31548415ffd --- /dev/null +++ b/tests/baselines/reference/commonJSReexport.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/salsa/main.js === +const { hardline } = require('./second').nested; +>hardline : Symbol(hardline, Decl(main.js, 0, 7)) +>require('./second').nested : Symbol(nested, Decl(second.js, 0, 18)) +>require : Symbol(require) +>'./second' : Symbol("tests/cases/conformance/salsa/second", Decl(second.js, 0, 0)) +>nested : Symbol(nested, Decl(second.js, 0, 18)) + +hardline +>hardline : Symbol(hardline, Decl(main.js, 0, 7)) + +=== tests/cases/conformance/salsa/first.js === +// #41422, based on prettier's exports + +const hardline = { type: "hard" } +>hardline : Symbol(hardline, Decl(first.js, 2, 5)) +>type : Symbol(type, Decl(first.js, 2, 18)) + +module.exports = { +>module.exports : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0)) +>module : Symbol(module, Decl(first.js, 2, 33)) +>exports : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0)) + + hardline +>hardline : Symbol(hardline, Decl(first.js, 3, 18)) +} + + +=== tests/cases/conformance/salsa/second.js === +module.exports = { +>module.exports : Symbol("tests/cases/conformance/salsa/second", Decl(second.js, 0, 0)) +>module : Symbol(export=, Decl(second.js, 0, 0)) +>exports : Symbol(export=, Decl(second.js, 0, 0)) + + nested: require('./first') +>nested : Symbol(nested, Decl(second.js, 0, 18)) +>require : Symbol(require) +>'./first' : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0)) + +}; + diff --git a/tests/baselines/reference/commonJSReexport.types b/tests/baselines/reference/commonJSReexport.types new file mode 100644 index 0000000000000..84e98c4fea008 --- /dev/null +++ b/tests/baselines/reference/commonJSReexport.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/salsa/main.js === +const { hardline } = require('./second').nested; +>hardline : { type: string; } +>require('./second').nested : typeof import("tests/cases/conformance/salsa/first") +>require('./second') : { nested: typeof import("tests/cases/conformance/salsa/first"); } +>require : any +>'./second' : "./second" +>nested : typeof import("tests/cases/conformance/salsa/first") + +hardline +>hardline : { type: string; } + +=== tests/cases/conformance/salsa/first.js === +// #41422, based on prettier's exports + +const hardline = { type: "hard" } +>hardline : { type: string; } +>{ type: "hard" } : { type: string; } +>type : string +>"hard" : "hard" + +module.exports = { +>module.exports = { hardline} : typeof import("tests/cases/conformance/salsa/first") +>module.exports : typeof import("tests/cases/conformance/salsa/first") +>module : { "\"tests/cases/conformance/salsa/first\"": typeof import("tests/cases/conformance/salsa/first"); } +>exports : typeof import("tests/cases/conformance/salsa/first") +>{ hardline} : { hardline: { type: string; }; } + + hardline +>hardline : { type: string; } +} + + +=== tests/cases/conformance/salsa/second.js === +module.exports = { +>module.exports = { nested: require('./first')} : { nested: typeof import("tests/cases/conformance/salsa/first"); } +>module.exports : { nested: typeof import("tests/cases/conformance/salsa/first"); } +>module : { "\"tests/cases/conformance/salsa/second\"": { nested: typeof import("tests/cases/conformance/salsa/first"); }; } +>exports : { nested: typeof import("tests/cases/conformance/salsa/first"); } +>{ nested: require('./first')} : { nested: typeof import("tests/cases/conformance/salsa/first"); } + + nested: require('./first') +>nested : typeof import("tests/cases/conformance/salsa/first") +>require('./first') : typeof import("tests/cases/conformance/salsa/first") +>require : any +>'./first' : "./first" + +}; + diff --git a/tests/cases/conformance/salsa/commonJSReexport.ts b/tests/cases/conformance/salsa/commonJSReexport.ts new file mode 100644 index 0000000000000..e3220c5c24842 --- /dev/null +++ b/tests/cases/conformance/salsa/commonJSReexport.ts @@ -0,0 +1,19 @@ +// #41422, based on prettier's exports +// @noEmit: true +// @checkJS: true + +// @filename: first.js +const hardline = { type: "hard" } +module.exports = { + hardline +} + + +// @filename: second.js +module.exports = { + nested: require('./first') +}; + +// @filename: main.js +const { hardline } = require('./second').nested; +hardline