Use JSDoc @type
tag type cast as a contextual type (#18690)
* Use JSDoc `@type` tag type cast as a contextual type * Suggested changes
This commit is contained in:
parent
a4b5870a52
commit
72c8b804da
3 changed files with 22 additions and 11 deletions
|
@ -13305,8 +13305,11 @@ namespace ts {
|
|||
case SyntaxKind.TemplateSpan:
|
||||
Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression);
|
||||
return getContextualTypeForSubstitutionExpression(<TemplateExpression>parent.parent, node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return getContextualType(<ParenthesizedExpression>parent);
|
||||
case SyntaxKind.ParenthesizedExpression: {
|
||||
// Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
|
||||
const tag = isInJavaScriptFile(parent) ? getJSDocTypeTag(parent) : undefined;
|
||||
return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(<ParenthesizedExpression>parent);
|
||||
}
|
||||
case SyntaxKind.JsxExpression:
|
||||
return getContextualTypeForJsxExpression(<JsxExpression>parent);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
|
@ -18127,13 +18130,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
|
||||
if (isInJavaScriptFile(node) && node.jsDoc) {
|
||||
const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag && !!(tag as JSDocTypeTag).typeExpression && !!(tag as JSDocTypeTag).typeExpression.type));
|
||||
if (typecasts && typecasts.length) {
|
||||
// We should have already issued an error if there were multiple type jsdocs
|
||||
const cast = typecasts[0] as JSDocTypeTag;
|
||||
return checkAssertionWorker(cast, cast.typeExpression.type, node.expression, checkMode);
|
||||
}
|
||||
const tag = isInJavaScriptFile(node) ? getJSDocTypeTag(node) : undefined;
|
||||
if (tag) {
|
||||
return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
|
||||
}
|
||||
return checkExpression(node.expression, checkMode);
|
||||
}
|
||||
|
|
|
@ -4091,9 +4091,14 @@ namespace ts {
|
|||
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
|
||||
}
|
||||
|
||||
/** Gets the JSDoc type tag for the node if present */
|
||||
/** Gets the JSDoc type tag for the node if present and valid */
|
||||
export function getJSDocTypeTag(node: Node): JSDocTypeTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
// We should have already issued an error if there were multiple type jsdocs, so just use the first one.
|
||||
const tag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
if (tag && tag.typeExpression && tag.typeExpression.type) {
|
||||
return tag;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
7
tests/cases/fourslash/completionsJsdocTypeTagCast.ts
Normal file
7
tests/cases/fourslash/completionsJsdocTypeTagCast.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowJs: true
|
||||
// @Filename: /a.js
|
||||
////const x = /** @type {{ s: string }} */ ({ /**/ });
|
||||
|
||||
verify.completionsAt("", ["s", "x"]);
|
Loading…
Reference in a new issue