Skip to content

Commit a21ac11

Browse files
authored
In JSDoc, resolve import types as values too (microsoft#26066)
* In JSDoc, resolve import types as values too This is something that we probably should have been doing for some time. Fixes microsoft#26049 * Fix whitespace lint
1 parent 4bc7f15 commit a21ac11

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8189,7 +8189,7 @@ namespace ts {
81898189
}
81908190

81918191
function isJSDocTypeReference(node: Node): node is TypeReferenceNode {
8192-
return !!(node.flags & NodeFlags.JSDoc) && node.kind === SyntaxKind.TypeReference;
8192+
return !!(node.flags & NodeFlags.JSDoc) && (node.kind === SyntaxKind.TypeReference || node.kind === SyntaxKind.ImportType);
81938193
}
81948194

81958195
function checkNoTypeArguments(node: NodeWithTypeArguments, symbol?: Symbol) {
@@ -9462,7 +9462,7 @@ namespace ts {
94629462
links.resolvedSymbol = unknownSymbol;
94639463
return links.resolvedType = errorType;
94649464
}
9465-
const targetMeaning = node.isTypeOf ? SymbolFlags.Value : SymbolFlags.Type;
9465+
const targetMeaning = node.isTypeOf ? SymbolFlags.Value : node.flags & NodeFlags.JSDoc ? SymbolFlags.Value | SymbolFlags.Type : SymbolFlags.Type;
94669466
// TODO: Future work: support unions/generics/whatever via a deferred import-type
94679467
const innerModuleSymbol = resolveExternalModuleName(node, node.argument.literal);
94689468
if (!innerModuleSymbol) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/conformance/jsdoc/type.js ===
2+
/** @typedef {import("./mod1").TestEnum} TE */
3+
/** @type {TE} */
4+
const test = 'add'
5+
>test : Symbol(test, Decl(type.js, 2, 5))
6+
7+
/** @type {import("./mod1").TestEnum} */
8+
const tost = 'remove'
9+
>tost : Symbol(tost, Decl(type.js, 4, 5))
10+
11+
=== tests/cases/conformance/jsdoc/value.js ===
12+
import { TestEnum } from "./mod1"
13+
>TestEnum : Symbol(TestEnum, Decl(value.js, 0, 8))
14+
15+
/** @type {TestEnum} */
16+
const tist = TestEnum.ADD
17+
>tist : Symbol(tist, Decl(value.js, 2, 5))
18+
>TestEnum.ADD : Symbol(ADD, Decl(mod1.js, 1, 25))
19+
>TestEnum : Symbol(TestEnum, Decl(value.js, 0, 8))
20+
>ADD : Symbol(ADD, Decl(mod1.js, 1, 25))
21+
22+
23+
=== tests/cases/conformance/jsdoc/mod1.js ===
24+
/** @enum {string} */
25+
export const TestEnum = {
26+
>TestEnum : Symbol(TestEnum, Decl(mod1.js, 1, 12))
27+
28+
ADD: 'add',
29+
>ADD : Symbol(ADD, Decl(mod1.js, 1, 25))
30+
31+
REMOVE: 'remove'
32+
>REMOVE : Symbol(REMOVE, Decl(mod1.js, 2, 15))
33+
}
34+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/conformance/jsdoc/type.js ===
2+
/** @typedef {import("./mod1").TestEnum} TE */
3+
/** @type {TE} */
4+
const test = 'add'
5+
>test : string
6+
>'add' : "add"
7+
8+
/** @type {import("./mod1").TestEnum} */
9+
const tost = 'remove'
10+
>tost : string
11+
>'remove' : "remove"
12+
13+
=== tests/cases/conformance/jsdoc/value.js ===
14+
import { TestEnum } from "./mod1"
15+
>TestEnum : { ADD: string; REMOVE: string; }
16+
17+
/** @type {TestEnum} */
18+
const tist = TestEnum.ADD
19+
>tist : string
20+
>TestEnum.ADD : string
21+
>TestEnum : { ADD: string; REMOVE: string; }
22+
>ADD : string
23+
24+
25+
=== tests/cases/conformance/jsdoc/mod1.js ===
26+
/** @enum {string} */
27+
export const TestEnum = {
28+
>TestEnum : { ADD: string; REMOVE: string; }
29+
>{ ADD: 'add', REMOVE: 'remove'} : { ADD: string; REMOVE: string; }
30+
31+
ADD: 'add',
32+
>ADD : string
33+
>'add' : "add"
34+
35+
REMOVE: 'remove'
36+
>REMOVE : string
37+
>'remove' : "remove"
38+
}
39+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
// @Filename: type.js
5+
/** @typedef {import("./mod1").TestEnum} TE */
6+
/** @type {TE} */
7+
const test = 'add'
8+
/** @type {import("./mod1").TestEnum} */
9+
const tost = 'remove'
10+
11+
// @Filename: value.js
12+
import { TestEnum } from "./mod1"
13+
/** @type {TestEnum} */
14+
const tist = TestEnum.ADD
15+
16+
17+
// @Filename: mod1.js
18+
19+
/** @enum {string} */
20+
export const TestEnum = {
21+
ADD: 'add',
22+
REMOVE: 'remove'
23+
}

0 commit comments

Comments
 (0)