mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Get [type] parameter types from @type tag (#26694)
* Get [type] parameter types from @type tag
Previously only the return type was used in cases like this:
```js
/** @type {<T>(param?: T) => T | undefined} */
function g(param) {
return param;
}
```
Now the type parameters from the type tag are used, and the compiler
gets the type of the parameter by using the position in the signature of
the type tag.
Fixes #25618
* Fix split ifs according to PR comments
This commit is contained in:
@@ -4699,6 +4699,12 @@ namespace ts {
|
||||
return getReturnTypeOfSignature(getterSignature);
|
||||
}
|
||||
}
|
||||
if (isInJavaScriptFile(declaration)) {
|
||||
const typeTag = getJSDocType(func);
|
||||
if (typeTag && isFunctionTypeNode(typeTag)) {
|
||||
return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration));
|
||||
}
|
||||
}
|
||||
// Use contextual parameter type if one is available
|
||||
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
|
||||
if (type) {
|
||||
|
||||
@@ -5116,7 +5116,20 @@ namespace ts {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
}
|
||||
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray);
|
||||
if (node.typeParameters) {
|
||||
return node.typeParameters;
|
||||
}
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const decls = getJSDocTypeParameterDeclarations(node);
|
||||
if (decls.length) {
|
||||
return decls;
|
||||
}
|
||||
const typeTag = getJSDocType(node);
|
||||
if (typeTag && isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
|
||||
return typeTag.typeParameters;
|
||||
}
|
||||
}
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
export function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/jsdoc/bug25618.js ===
|
||||
/** @type {<T>(param?: T) => T | undefined} */
|
||||
function typed(param) {
|
||||
>typed : Symbol(typed, Decl(bug25618.js, 0, 0))
|
||||
>param : Symbol(param, Decl(bug25618.js, 1, 15))
|
||||
|
||||
return param;
|
||||
>param : Symbol(param, Decl(bug25618.js, 1, 15))
|
||||
}
|
||||
|
||||
var n = typed(1);
|
||||
>n : Symbol(n, Decl(bug25618.js, 5, 3))
|
||||
>typed : Symbol(typed, Decl(bug25618.js, 0, 0))
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/conformance/jsdoc/bug25618.js ===
|
||||
/** @type {<T>(param?: T) => T | undefined} */
|
||||
function typed(param) {
|
||||
>typed : <T>(param: T | undefined) => T | undefined
|
||||
>param : T | undefined
|
||||
|
||||
return param;
|
||||
>param : T | undefined
|
||||
}
|
||||
|
||||
var n = typed(1);
|
||||
>n : number | undefined
|
||||
>typed(1) : 1 | undefined
|
||||
>typed : <T>(param: T | undefined) => T | undefined
|
||||
>1 : 1
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
// @strict: true
|
||||
// @Filename: bug25618.js
|
||||
|
||||
/** @type {<T>(param?: T) => T | undefined} */
|
||||
function typed(param) {
|
||||
return param;
|
||||
}
|
||||
|
||||
var n = typed(1);
|
||||
|
||||
Reference in New Issue
Block a user