Skip to content

Commit c06a30a

Browse files
authored
JSDoc Instantiation Fixes (#17553)
* Fix #17383 - issue an error when jsdoc attempts to instantiate a builtin as a generic * Fix comment * Fix #17377 - only get type parameters from reference target if the type is a reference * Fix #17525 - Add SyntaxKind.AsteriskToken to isStartOfType
1 parent 4672457 commit c06a30a

7 files changed

+214
-1
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18594,7 +18594,17 @@ namespace ts {
1859418594
forEach(node.typeArguments, checkSourceElement);
1859518595
if (produceDiagnostics) {
1859618596
const symbol = getNodeLinks(node).resolvedSymbol;
18597-
const typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks(symbol).typeParameters : (<TypeReference>type).target.localTypeParameters;
18597+
if (!symbol) {
18598+
// There is no resolved symbol cached if the type resolved to a builtin
18599+
// via JSDoc type reference resolution (eg, Boolean became boolean), none
18600+
// of which are generic when they have no associated symbol
18601+
error(node, Diagnostics.Type_0_is_not_generic, typeToString(type));
18602+
return;
18603+
}
18604+
let typeParameters = symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters;
18605+
if (!typeParameters && getObjectFlags(type) & ObjectFlags.Reference) {
18606+
typeParameters = (<TypeReference>type).target.localTypeParameters;
18607+
}
1859818608
checkTypeArgumentConstraints(typeParameters, node.typeArguments);
1859918609
}
1860018610
}

src/compiler/parser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,7 @@ namespace ts {
27002700
case SyntaxKind.TrueKeyword:
27012701
case SyntaxKind.FalseKeyword:
27022702
case SyntaxKind.ObjectKeyword:
2703+
case SyntaxKind.AsteriskToken:
27032704
return true;
27042705
case SyntaxKind.MinusToken:
27052706
return lookAhead(nextTokenIsNumericLiteral);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/compiler/index.js ===
2+
/**
3+
* @param {Array<*>} list
4+
*/
5+
function thing(list) {
6+
>thing : Symbol(thing, Decl(index.js, 0, 0))
7+
>list : Symbol(list, Decl(index.js, 3, 15))
8+
9+
return list;
10+
>list : Symbol(list, Decl(index.js, 3, 15))
11+
}
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/compiler/index.js ===
2+
/**
3+
* @param {Array<*>} list
4+
*/
5+
function thing(list) {
6+
>thing : (list: any[]) => any[]
7+
>list : any[]
8+
9+
return list;
10+
>list : any[]
11+
}
12+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
tests/cases/compiler/index.js(2,19): error TS2315: Type 'boolean' is not generic.
2+
tests/cases/compiler/index2.js(2,19): error TS2315: Type 'void' is not generic.
3+
tests/cases/compiler/index3.js(2,19): error TS2315: Type 'undefined' is not generic.
4+
tests/cases/compiler/index4.js(2,19): error TS2315: Type 'Function' is not generic.
5+
tests/cases/compiler/index5.js(2,19): error TS2315: Type 'string' is not generic.
6+
tests/cases/compiler/index6.js(2,19): error TS2315: Type 'number' is not generic.
7+
tests/cases/compiler/index7.js(2,19): error TS2315: Type 'any' is not generic.
8+
tests/cases/compiler/index8.js(4,12): error TS2304: Cannot find name 'fn'.
9+
tests/cases/compiler/index8.js(4,15): error TS2304: Cannot find name 'T'.
10+
11+
12+
==== tests/cases/compiler/index.js (1 errors) ====
13+
/**
14+
* @param {<T>(m: Boolean<T>) => string} somebody
15+
~~~~~~~~~~
16+
!!! error TS2315: Type 'boolean' is not generic.
17+
*/
18+
function sayHello(somebody) {
19+
return 'Hello ' + somebody;
20+
}
21+
22+
==== tests/cases/compiler/index2.js (1 errors) ====
23+
/**
24+
* @param {<T>(m: Void<T>) => string} somebody
25+
~~~~~~~
26+
!!! error TS2315: Type 'void' is not generic.
27+
*/
28+
function sayHello2(somebody) {
29+
return 'Hello ' + somebody;
30+
}
31+
32+
33+
==== tests/cases/compiler/index3.js (1 errors) ====
34+
/**
35+
* @param {<T>(m: Undefined<T>) => string} somebody
36+
~~~~~~~~~~~~
37+
!!! error TS2315: Type 'undefined' is not generic.
38+
*/
39+
function sayHello3(somebody) {
40+
return 'Hello ' + somebody;
41+
}
42+
43+
44+
==== tests/cases/compiler/index4.js (1 errors) ====
45+
/**
46+
* @param {<T>(m: Function<T>) => string} somebody
47+
~~~~~~~~~~~
48+
!!! error TS2315: Type 'Function' is not generic.
49+
*/
50+
function sayHello4(somebody) {
51+
return 'Hello ' + somebody;
52+
}
53+
54+
55+
==== tests/cases/compiler/index5.js (1 errors) ====
56+
/**
57+
* @param {<T>(m: String<T>) => string} somebody
58+
~~~~~~~~~
59+
!!! error TS2315: Type 'string' is not generic.
60+
*/
61+
function sayHello5(somebody) {
62+
return 'Hello ' + somebody;
63+
}
64+
65+
66+
==== tests/cases/compiler/index6.js (1 errors) ====
67+
/**
68+
* @param {<T>(m: Number<T>) => string} somebody
69+
~~~~~~~~~
70+
!!! error TS2315: Type 'number' is not generic.
71+
*/
72+
function sayHello6(somebody) {
73+
return 'Hello ' + somebody;
74+
}
75+
76+
77+
==== tests/cases/compiler/index7.js (1 errors) ====
78+
/**
79+
* @param {<T>(m: Object<T>) => string} somebody
80+
~~~~~~~~~
81+
!!! error TS2315: Type 'any' is not generic.
82+
*/
83+
function sayHello7(somebody) {
84+
return 'Hello ' + somebody;
85+
}
86+
87+
==== tests/cases/compiler/index8.js (2 errors) ====
88+
function fn() {}
89+
90+
/**
91+
* @param {fn<T>} somebody
92+
~~
93+
!!! error TS2304: Cannot find name 'fn'.
94+
~
95+
!!! error TS2304: Cannot find name 'T'.
96+
*/
97+
function sayHello8(somebody) { }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @filename: index.js
5+
/**
6+
* @param {Array<*>} list
7+
*/
8+
function thing(list) {
9+
return list;
10+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @filename: index.js
5+
/**
6+
* @param {<T>(m: Boolean<T>) => string} somebody
7+
*/
8+
function sayHello(somebody) {
9+
return 'Hello ' + somebody;
10+
}
11+
12+
// @filename: index2.js
13+
/**
14+
* @param {<T>(m: Void<T>) => string} somebody
15+
*/
16+
function sayHello2(somebody) {
17+
return 'Hello ' + somebody;
18+
}
19+
20+
21+
// @filename: index3.js
22+
/**
23+
* @param {<T>(m: Undefined<T>) => string} somebody
24+
*/
25+
function sayHello3(somebody) {
26+
return 'Hello ' + somebody;
27+
}
28+
29+
30+
// @filename: index4.js
31+
/**
32+
* @param {<T>(m: Function<T>) => string} somebody
33+
*/
34+
function sayHello4(somebody) {
35+
return 'Hello ' + somebody;
36+
}
37+
38+
39+
// @filename: index5.js
40+
/**
41+
* @param {<T>(m: String<T>) => string} somebody
42+
*/
43+
function sayHello5(somebody) {
44+
return 'Hello ' + somebody;
45+
}
46+
47+
48+
// @filename: index6.js
49+
/**
50+
* @param {<T>(m: Number<T>) => string} somebody
51+
*/
52+
function sayHello6(somebody) {
53+
return 'Hello ' + somebody;
54+
}
55+
56+
57+
// @filename: index7.js
58+
/**
59+
* @param {<T>(m: Object<T>) => string} somebody
60+
*/
61+
function sayHello7(somebody) {
62+
return 'Hello ' + somebody;
63+
}
64+
65+
// @filename: index8.js
66+
function fn() {}
67+
68+
/**
69+
* @param {fn<T>} somebody
70+
*/
71+
function sayHello8(somebody) { }

0 commit comments

Comments
 (0)