@@ -8388,12 +8388,12 @@ namespace ts {
8388
8388
}
8389
8389
8390
8390
function isNullOrUndefined(node: Expression) {
8391
- const expr = skipParentheses(node);
8391
+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
8392
8392
return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol;
8393
8393
}
8394
8394
8395
8395
function isEmptyArrayLiteral(node: Expression) {
8396
- const expr = skipParentheses(node);
8396
+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
8397
8397
return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
8398
8398
}
8399
8399
@@ -22956,7 +22956,7 @@ namespace ts {
22956
22956
}
22957
22957
22958
22958
function isFalseExpression(expr: Expression): boolean {
22959
- const node = skipParentheses(expr);
22959
+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
22960
22960
return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
22961
22961
(node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
22962
22962
(node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23278,7 +23278,7 @@ namespace ts {
23278
23278
}
23279
23279
23280
23280
function narrowTypeByAssertion(type: Type, expr: Expression): Type {
23281
- const node = skipParentheses(expr);
23281
+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
23282
23282
if (node.kind === SyntaxKind.FalseKeyword) {
23283
23283
return unreachableNeverType;
23284
23284
}
@@ -25858,7 +25858,9 @@ namespace ts {
25858
25858
case SyntaxKind.ParenthesizedExpression: {
25859
25859
// Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
25860
25860
const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
25861
- return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent as ParenthesizedExpression, contextFlags);
25861
+ return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) :
25862
+ isJSDocTypeTag(tag) && isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ParenthesizedExpression) :
25863
+ getTypeFromTypeNode(tag.typeExpression.type);
25862
25864
}
25863
25865
case SyntaxKind.NonNullExpression:
25864
25866
return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32768,8 +32770,10 @@ namespace ts {
32768
32770
}
32769
32771
32770
32772
function isTypeAssertion(node: Expression) {
32771
- node = skipParentheses(node);
32772
- return node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression;
32773
+ node = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
32774
+ return node.kind === SyntaxKind.TypeAssertionExpression ||
32775
+ node.kind === SyntaxKind.AsExpression ||
32776
+ isJSDocTypeAssertion(node);
32773
32777
}
32774
32778
32775
32779
function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32844,6 +32848,7 @@ namespace ts {
32844
32848
function isConstContext(node: Expression): boolean {
32845
32849
const parent = node.parent;
32846
32850
return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
32851
+ isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
32847
32852
(isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
32848
32853
(isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
32849
32854
}
@@ -33056,7 +33061,14 @@ namespace ts {
33056
33061
}
33057
33062
33058
33063
function getQuickTypeOfExpression(node: Expression) {
33059
- const expr = skipParentheses(node);
33064
+ let expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
33065
+ if (isJSDocTypeAssertion(expr)) {
33066
+ const type = getJSDocTypeAssertionType(expr);
33067
+ if (!isConstTypeReference(type)) {
33068
+ return getTypeFromTypeNode(type);
33069
+ }
33070
+ }
33071
+ expr = skipParentheses(node);
33060
33072
// Optimize for the common case of a call to a function with a single non-generic call
33061
33073
// signature where we can just fetch the return type without checking the arguments.
33062
33074
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33143,9 +33155,9 @@ namespace ts {
33143
33155
}
33144
33156
33145
33157
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
33146
- const tag = isInJSFile(node) ? getJSDocTypeTag (node) : undefined;
33147
- if (tag) {
33148
- return checkAssertionWorker(tag.typeExpression. type, tag.typeExpression. type, node.expression, checkMode);
33158
+ if (isJSDocTypeAssertion (node)) {
33159
+ const type = getJSDocTypeAssertionType(node);
33160
+ return checkAssertionWorker(type, type, node.expression, checkMode);
33149
33161
}
33150
33162
return checkExpression(node.expression, checkMode);
33151
33163
}
@@ -36093,7 +36105,7 @@ namespace ts {
36093
36105
if (getFalsyFlags(type)) return;
36094
36106
36095
36107
const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
36096
- if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses( location.expression) )) {
36108
+ if (isPropertyAccessExpression(location) && isTypeAssertion( location.expression)) {
36097
36109
return;
36098
36110
}
36099
36111
0 commit comments