Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
17 changes: 16 additions & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5120,7 +5120,22 @@ 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) {
if (isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the nested if?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason! Fixed.

return typeTag.typeParameters;
}
}
}
return emptyArray;
}

export function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined {
Expand Down
15 changes: 15 additions & 0 deletions tests/baselines/reference/typeTagWithGenericSignature.symbols
Original file line number Diff line number Diff line change
@@ -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))


17 changes: 17 additions & 0 deletions tests/baselines/reference/typeTagWithGenericSignature.types
Original file line number Diff line number Diff line change
@@ -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


13 changes: 13 additions & 0 deletions tests/cases/conformance/jsdoc/typeTagWithGenericSignature.ts
Original file line number Diff line number Diff line change
@@ -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);