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
This commit is contained in:
parent
467245780d
commit
c06a30ae68
|
@ -18594,7 +18594,17 @@ namespace ts {
|
|||
forEach(node.typeArguments, checkSourceElement);
|
||||
if (produceDiagnostics) {
|
||||
const symbol = getNodeLinks(node).resolvedSymbol;
|
||||
const typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks(symbol).typeParameters : (<TypeReference>type).target.localTypeParameters;
|
||||
if (!symbol) {
|
||||
// There is no resolved symbol cached if the type resolved to a builtin
|
||||
// via JSDoc type reference resolution (eg, Boolean became boolean), none
|
||||
// of which are generic when they have no associated symbol
|
||||
error(node, Diagnostics.Type_0_is_not_generic, typeToString(type));
|
||||
return;
|
||||
}
|
||||
let typeParameters = symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters;
|
||||
if (!typeParameters && getObjectFlags(type) & ObjectFlags.Reference) {
|
||||
typeParameters = (<TypeReference>type).target.localTypeParameters;
|
||||
}
|
||||
checkTypeArgumentConstraints(typeParameters, node.typeArguments);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2700,6 +2700,7 @@ namespace ts {
|
|||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.AsteriskToken:
|
||||
return true;
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
=== tests/cases/compiler/index.js ===
|
||||
/**
|
||||
* @param {Array<*>} list
|
||||
*/
|
||||
function thing(list) {
|
||||
>thing : Symbol(thing, Decl(index.js, 0, 0))
|
||||
>list : Symbol(list, Decl(index.js, 3, 15))
|
||||
|
||||
return list;
|
||||
>list : Symbol(list, Decl(index.js, 3, 15))
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
=== tests/cases/compiler/index.js ===
|
||||
/**
|
||||
* @param {Array<*>} list
|
||||
*/
|
||||
function thing(list) {
|
||||
>thing : (list: any[]) => any[]
|
||||
>list : any[]
|
||||
|
||||
return list;
|
||||
>list : any[]
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
tests/cases/compiler/index.js(2,19): error TS2315: Type 'boolean' is not generic.
|
||||
tests/cases/compiler/index2.js(2,19): error TS2315: Type 'void' is not generic.
|
||||
tests/cases/compiler/index3.js(2,19): error TS2315: Type 'undefined' is not generic.
|
||||
tests/cases/compiler/index4.js(2,19): error TS2315: Type 'Function' is not generic.
|
||||
tests/cases/compiler/index5.js(2,19): error TS2315: Type 'string' is not generic.
|
||||
tests/cases/compiler/index6.js(2,19): error TS2315: Type 'number' is not generic.
|
||||
tests/cases/compiler/index7.js(2,19): error TS2315: Type 'any' is not generic.
|
||||
tests/cases/compiler/index8.js(4,12): error TS2304: Cannot find name 'fn'.
|
||||
tests/cases/compiler/index8.js(4,15): error TS2304: Cannot find name 'T'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/index.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Boolean<T>) => string} somebody
|
||||
~~~~~~~~~~
|
||||
!!! error TS2315: Type 'boolean' is not generic.
|
||||
*/
|
||||
function sayHello(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/index2.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Void<T>) => string} somebody
|
||||
~~~~~~~
|
||||
!!! error TS2315: Type 'void' is not generic.
|
||||
*/
|
||||
function sayHello2(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
==== tests/cases/compiler/index3.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Undefined<T>) => string} somebody
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2315: Type 'undefined' is not generic.
|
||||
*/
|
||||
function sayHello3(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
==== tests/cases/compiler/index4.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Function<T>) => string} somebody
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2315: Type 'Function' is not generic.
|
||||
*/
|
||||
function sayHello4(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
==== tests/cases/compiler/index5.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: String<T>) => string} somebody
|
||||
~~~~~~~~~
|
||||
!!! error TS2315: Type 'string' is not generic.
|
||||
*/
|
||||
function sayHello5(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
==== tests/cases/compiler/index6.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Number<T>) => string} somebody
|
||||
~~~~~~~~~
|
||||
!!! error TS2315: Type 'number' is not generic.
|
||||
*/
|
||||
function sayHello6(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
==== tests/cases/compiler/index7.js (1 errors) ====
|
||||
/**
|
||||
* @param {<T>(m: Object<T>) => string} somebody
|
||||
~~~~~~~~~
|
||||
!!! error TS2315: Type 'any' is not generic.
|
||||
*/
|
||||
function sayHello7(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/index8.js (2 errors) ====
|
||||
function fn() {}
|
||||
|
||||
/**
|
||||
* @param {fn<T>} somebody
|
||||
~~
|
||||
!!! error TS2304: Cannot find name 'fn'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
*/
|
||||
function sayHello8(somebody) { }
|
10
tests/cases/compiler/jsdocTypeGenericInstantiationAttempt.ts
Normal file
10
tests/cases/compiler/jsdocTypeGenericInstantiationAttempt.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
// @filename: index.js
|
||||
/**
|
||||
* @param {Array<*>} list
|
||||
*/
|
||||
function thing(list) {
|
||||
return list;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
// @filename: index.js
|
||||
/**
|
||||
* @param {<T>(m: Boolean<T>) => string} somebody
|
||||
*/
|
||||
function sayHello(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
// @filename: index2.js
|
||||
/**
|
||||
* @param {<T>(m: Void<T>) => string} somebody
|
||||
*/
|
||||
function sayHello2(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
// @filename: index3.js
|
||||
/**
|
||||
* @param {<T>(m: Undefined<T>) => string} somebody
|
||||
*/
|
||||
function sayHello3(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
// @filename: index4.js
|
||||
/**
|
||||
* @param {<T>(m: Function<T>) => string} somebody
|
||||
*/
|
||||
function sayHello4(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
// @filename: index5.js
|
||||
/**
|
||||
* @param {<T>(m: String<T>) => string} somebody
|
||||
*/
|
||||
function sayHello5(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
// @filename: index6.js
|
||||
/**
|
||||
* @param {<T>(m: Number<T>) => string} somebody
|
||||
*/
|
||||
function sayHello6(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
|
||||
// @filename: index7.js
|
||||
/**
|
||||
* @param {<T>(m: Object<T>) => string} somebody
|
||||
*/
|
||||
function sayHello7(somebody) {
|
||||
return 'Hello ' + somebody;
|
||||
}
|
||||
|
||||
// @filename: index8.js
|
||||
function fn() {}
|
||||
|
||||
/**
|
||||
* @param {fn<T>} somebody
|
||||
*/
|
||||
function sayHello8(somebody) { }
|
Loading…
Reference in a new issue