Skip to content

Commit b713df8

Browse files
committed
resolve require with entity name postfix
For example, `require("x").c`. This is the value equivalent of `import("x").a.b.c`, but the syntax tree is not as nicely designed for this purpose. Fixes #34802
1 parent 554bd24 commit b713df8

File tree

4 files changed

+95
-5
lines changed

4 files changed

+95
-5
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10765,11 +10765,15 @@ namespace ts {
1076510765
let typeType = valueType;
1076610766
if (symbol.valueDeclaration) {
1076710767
const decl = getRootDeclaration(symbol.valueDeclaration);
10768-
const isRequireAlias = isVariableDeclaration(decl)
10769-
&& decl.initializer
10770-
&& isCallExpression(decl.initializer)
10771-
&& isRequireCall(decl.initializer, /*requireStringLiteralLikeArgument*/ true)
10772-
&& valueType.symbol;
10768+
let isRequireAlias = false;
10769+
if (isVariableDeclaration(decl) && decl.initializer) {
10770+
let expr = decl.initializer;
10771+
// skip past entity names, eg `require("x").a.b.c`
10772+
while (isPropertyAccessExpression(expr)) {
10773+
expr = expr.expression;
10774+
}
10775+
isRequireAlias = isCallExpression(expr) && isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !!valueType.symbol;
10776+
}
1077310777
if (isRequireAlias || node.kind === SyntaxKind.ImportType) {
1077410778
typeType = getTypeReferenceType(node, valueType.symbol);
1077510779
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/conformance/jsdoc/jsdocTypeReferenceToImport.js ===
2+
const C = require('./ex').C;
3+
>C : Symbol(C, Decl(jsdocTypeReferenceToImport.js, 0, 5))
4+
>require('./ex').C : Symbol(C, Decl(ex.d.ts, 0, 0))
5+
>require : Symbol(require)
6+
>'./ex' : Symbol("tests/cases/conformance/jsdoc/ex", Decl(ex.d.ts, 0, 0))
7+
>C : Symbol(C, Decl(ex.d.ts, 0, 0))
8+
9+
/** @type {C} c */
10+
var c = new C()
11+
>c : Symbol(c, Decl(jsdocTypeReferenceToImport.js, 2, 3))
12+
>C : Symbol(C, Decl(jsdocTypeReferenceToImport.js, 0, 5))
13+
14+
c.start
15+
>c.start : Symbol(C.start, Decl(ex.d.ts, 0, 16))
16+
>c : Symbol(c, Decl(jsdocTypeReferenceToImport.js, 2, 3))
17+
>start : Symbol(C.start, Decl(ex.d.ts, 0, 16))
18+
19+
c.end
20+
>c.end : Symbol(C.end, Decl(ex.d.ts, 1, 17))
21+
>c : Symbol(c, Decl(jsdocTypeReferenceToImport.js, 2, 3))
22+
>end : Symbol(C.end, Decl(ex.d.ts, 1, 17))
23+
24+
=== tests/cases/conformance/jsdoc/ex.d.ts ===
25+
export class C {
26+
>C : Symbol(C, Decl(ex.d.ts, 0, 0))
27+
28+
start: number
29+
>start : Symbol(C.start, Decl(ex.d.ts, 0, 16))
30+
31+
end: number
32+
>end : Symbol(C.end, Decl(ex.d.ts, 1, 17))
33+
}
34+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/jsdoc/jsdocTypeReferenceToImport.js ===
2+
const C = require('./ex').C;
3+
>C : typeof import("tests/cases/conformance/jsdoc/ex").C
4+
>require('./ex').C : typeof import("tests/cases/conformance/jsdoc/ex").C
5+
>require('./ex') : typeof import("tests/cases/conformance/jsdoc/ex")
6+
>require : any
7+
>'./ex' : "./ex"
8+
>C : typeof import("tests/cases/conformance/jsdoc/ex").C
9+
10+
/** @type {C} c */
11+
var c = new C()
12+
>c : import("tests/cases/conformance/jsdoc/ex").C
13+
>new C() : import("tests/cases/conformance/jsdoc/ex").C
14+
>C : typeof import("tests/cases/conformance/jsdoc/ex").C
15+
16+
c.start
17+
>c.start : number
18+
>c : import("tests/cases/conformance/jsdoc/ex").C
19+
>start : number
20+
21+
c.end
22+
>c.end : number
23+
>c : import("tests/cases/conformance/jsdoc/ex").C
24+
>end : number
25+
26+
=== tests/cases/conformance/jsdoc/ex.d.ts ===
27+
export class C {
28+
>C : C
29+
30+
start: number
31+
>start : number
32+
33+
end: number
34+
>end : number
35+
}
36+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @Filename: jsdocTypeReferenceToImport.js
2+
// @noEmit: true
3+
// @allowJs: true
4+
// @checkJs: true
5+
6+
const C = require('./ex').C;
7+
/** @type {C} c */
8+
var c = new C()
9+
c.start
10+
c.end
11+
12+
// @Filename: ex.d.ts
13+
export class C {
14+
start: number
15+
end: number
16+
}

0 commit comments

Comments
 (0)