Fix commonjs require of ES export (#40221)

The commonjs-specific code for resolving access expressions on `require`
assumes a fake commonjs export. For real exports, it needs to call
resolveSymbol since it's outside the normal alias-resolving
infrastructure.
This commit is contained in:
Nathan Shively-Sanders
2020-08-24 12:37:25 -07:00
committed by GitHub
parent 31fab0fb1e
commit 4aadd5af41
6 changed files with 134 additions and 1 deletions

View File

@@ -2412,7 +2412,7 @@ namespace ts {
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
const name = (getLeftmostPropertyAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
return isIdentifier(node.initializer.name)
? getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText)
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText))
: undefined;
}
if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {

View File

@@ -0,0 +1,16 @@
tests/cases/conformance/salsa/main.js(4,3): error TS2339: Property 'x' does not exist on type '{ grey: {}; }'.
==== tests/cases/conformance/salsa/main.js (1 errors) ====
const x = require('./ch').x
x
x.grey
x.x.grey
~
!!! error TS2339: Property 'x' does not exist on type '{ grey: {}; }'.
==== tests/cases/conformance/salsa/ch.js (0 errors) ====
const x = {
grey: {}
}
export { x }

View File

@@ -0,0 +1,36 @@
//// [tests/cases/conformance/salsa/requireOfESWithPropertyAccess.ts] ////
//// [main.js]
const x = require('./ch').x
x
x.grey
x.x.grey
//// [ch.js]
const x = {
grey: {}
}
export { x }
//// [ch.js]
"use strict";
exports.__esModule = true;
exports.x = void 0;
var x = {
grey: {}
};
exports.x = x;
//// [main.js]
"use strict";
var x = require('./ch').x;
x;
x.grey;
x.x.grey;
//// [ch.d.ts]
export namespace x {
const grey: {};
}
//// [main.d.ts]
export {};

View File

@@ -0,0 +1,29 @@
=== tests/cases/conformance/salsa/main.js ===
const x = require('./ch').x
>x : Symbol(x, Decl(main.js, 0, 5))
>require('./ch').x : Symbol(x, Decl(ch.js, 3, 8))
>require : Symbol(require)
>'./ch' : Symbol("tests/cases/conformance/salsa/ch", Decl(ch.js, 0, 0))
>x : Symbol(x, Decl(ch.js, 3, 8))
x
>x : Symbol(x, Decl(main.js, 0, 5))
x.grey
>x.grey : Symbol(grey, Decl(ch.js, 0, 11))
>x : Symbol(x, Decl(main.js, 0, 5))
>grey : Symbol(grey, Decl(ch.js, 0, 11))
x.x.grey
>x : Symbol(x, Decl(main.js, 0, 5))
=== tests/cases/conformance/salsa/ch.js ===
const x = {
>x : Symbol(x, Decl(ch.js, 0, 5))
grey: {}
>grey : Symbol(grey, Decl(ch.js, 0, 11))
}
export { x }
>x : Symbol(x, Decl(ch.js, 3, 8))

View File

@@ -0,0 +1,36 @@
=== tests/cases/conformance/salsa/main.js ===
const x = require('./ch').x
>x : { grey: {}; }
>require('./ch').x : { grey: {}; }
>require('./ch') : typeof import("tests/cases/conformance/salsa/ch")
>require : any
>'./ch' : "./ch"
>x : { grey: {}; }
x
>x : { grey: {}; }
x.grey
>x.grey : {}
>x : { grey: {}; }
>grey : {}
x.x.grey
>x.x.grey : any
>x.x : any
>x : { grey: {}; }
>x : any
>grey : any
=== tests/cases/conformance/salsa/ch.js ===
const x = {
>x : { grey: {}; }
>{ grey: {}} : { grey: {}; }
grey: {}
>grey : {}
>{} : {}
}
export { x }
>x : { grey: {}; }

View File

@@ -0,0 +1,16 @@
// @allowJs: true
// @checkJs: true
// @strict: true
// @outDir: out
// @declaration: true
// @filename: main.js
const x = require('./ch').x
x
x.grey
x.x.grey
// @filename: ch.js
const x = {
grey: {}
}
export { x }