Skip to content

Commit 4aadd5a

Browse files
authored
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.
1 parent 31fab0f commit 4aadd5a

6 files changed

+134
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2412,7 +2412,7 @@ namespace ts {
24122412
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
24132413
const name = (getLeftmostPropertyAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
24142414
return isIdentifier(node.initializer.name)
2415-
? getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText)
2415+
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText))
24162416
: undefined;
24172417
}
24182418
if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/conformance/salsa/main.js(4,3): error TS2339: Property 'x' does not exist on type '{ grey: {}; }'.
2+
3+
4+
==== tests/cases/conformance/salsa/main.js (1 errors) ====
5+
const x = require('./ch').x
6+
x
7+
x.grey
8+
x.x.grey
9+
~
10+
!!! error TS2339: Property 'x' does not exist on type '{ grey: {}; }'.
11+
==== tests/cases/conformance/salsa/ch.js (0 errors) ====
12+
const x = {
13+
grey: {}
14+
}
15+
export { x }
16+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/conformance/salsa/requireOfESWithPropertyAccess.ts] ////
2+
3+
//// [main.js]
4+
const x = require('./ch').x
5+
x
6+
x.grey
7+
x.x.grey
8+
//// [ch.js]
9+
const x = {
10+
grey: {}
11+
}
12+
export { x }
13+
14+
15+
//// [ch.js]
16+
"use strict";
17+
exports.__esModule = true;
18+
exports.x = void 0;
19+
var x = {
20+
grey: {}
21+
};
22+
exports.x = x;
23+
//// [main.js]
24+
"use strict";
25+
var x = require('./ch').x;
26+
x;
27+
x.grey;
28+
x.x.grey;
29+
30+
31+
//// [ch.d.ts]
32+
export namespace x {
33+
const grey: {};
34+
}
35+
//// [main.d.ts]
36+
export {};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/conformance/salsa/main.js ===
2+
const x = require('./ch').x
3+
>x : Symbol(x, Decl(main.js, 0, 5))
4+
>require('./ch').x : Symbol(x, Decl(ch.js, 3, 8))
5+
>require : Symbol(require)
6+
>'./ch' : Symbol("tests/cases/conformance/salsa/ch", Decl(ch.js, 0, 0))
7+
>x : Symbol(x, Decl(ch.js, 3, 8))
8+
9+
x
10+
>x : Symbol(x, Decl(main.js, 0, 5))
11+
12+
x.grey
13+
>x.grey : Symbol(grey, Decl(ch.js, 0, 11))
14+
>x : Symbol(x, Decl(main.js, 0, 5))
15+
>grey : Symbol(grey, Decl(ch.js, 0, 11))
16+
17+
x.x.grey
18+
>x : Symbol(x, Decl(main.js, 0, 5))
19+
20+
=== tests/cases/conformance/salsa/ch.js ===
21+
const x = {
22+
>x : Symbol(x, Decl(ch.js, 0, 5))
23+
24+
grey: {}
25+
>grey : Symbol(grey, Decl(ch.js, 0, 11))
26+
}
27+
export { x }
28+
>x : Symbol(x, Decl(ch.js, 3, 8))
29+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/salsa/main.js ===
2+
const x = require('./ch').x
3+
>x : { grey: {}; }
4+
>require('./ch').x : { grey: {}; }
5+
>require('./ch') : typeof import("tests/cases/conformance/salsa/ch")
6+
>require : any
7+
>'./ch' : "./ch"
8+
>x : { grey: {}; }
9+
10+
x
11+
>x : { grey: {}; }
12+
13+
x.grey
14+
>x.grey : {}
15+
>x : { grey: {}; }
16+
>grey : {}
17+
18+
x.x.grey
19+
>x.x.grey : any
20+
>x.x : any
21+
>x : { grey: {}; }
22+
>x : any
23+
>grey : any
24+
25+
=== tests/cases/conformance/salsa/ch.js ===
26+
const x = {
27+
>x : { grey: {}; }
28+
>{ grey: {}} : { grey: {}; }
29+
30+
grey: {}
31+
>grey : {}
32+
>{} : {}
33+
}
34+
export { x }
35+
>x : { grey: {}; }
36+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @strict: true
4+
// @outDir: out
5+
// @declaration: true
6+
7+
// @filename: main.js
8+
const x = require('./ch').x
9+
x
10+
x.grey
11+
x.x.grey
12+
// @filename: ch.js
13+
const x = {
14+
grey: {}
15+
}
16+
export { x }

0 commit comments

Comments
 (0)