@@ -8402,12 +8402,12 @@ namespace ts {
8402
8402
}
8403
8403
8404
8404
function isNullOrUndefined(node: Expression) {
8405
- const expr = skipParentheses(node);
8405
+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
8406
8406
return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol;
8407
8407
}
8408
8408
8409
8409
function isEmptyArrayLiteral(node: Expression) {
8410
- const expr = skipParentheses(node);
8410
+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
8411
8411
return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
8412
8412
}
8413
8413
@@ -22968,7 +22968,7 @@ namespace ts {
22968
22968
}
22969
22969
22970
22970
function isFalseExpression(expr: Expression): boolean {
22971
- const node = skipParentheses(expr);
22971
+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
22972
22972
return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
22973
22973
(node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
22974
22974
(node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23290,7 +23290,7 @@ namespace ts {
23290
23290
}
23291
23291
23292
23292
function narrowTypeByAssertion(type: Type, expr: Expression): Type {
23293
- const node = skipParentheses(expr);
23293
+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
23294
23294
if (node.kind === SyntaxKind.FalseKeyword) {
23295
23295
return unreachableNeverType;
23296
23296
}
@@ -25874,7 +25874,9 @@ namespace ts {
25874
25874
case SyntaxKind.ParenthesizedExpression: {
25875
25875
// Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
25876
25876
const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
25877
- return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent as ParenthesizedExpression, contextFlags);
25877
+ return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) :
25878
+ isJSDocTypeTag(tag) && isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ParenthesizedExpression) :
25879
+ getTypeFromTypeNode(tag.typeExpression.type);
25878
25880
}
25879
25881
case SyntaxKind.NonNullExpression:
25880
25882
return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32857,8 +32859,10 @@ namespace ts {
32857
32859
}
32858
32860
32859
32861
function isTypeAssertion(node: Expression) {
32860
- node = skipParentheses(node);
32861
- return node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression;
32862
+ node = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
32863
+ return node.kind === SyntaxKind.TypeAssertionExpression ||
32864
+ node.kind === SyntaxKind.AsExpression ||
32865
+ isJSDocTypeAssertion(node);
32862
32866
}
32863
32867
32864
32868
function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32933,6 +32937,7 @@ namespace ts {
32933
32937
function isConstContext(node: Expression): boolean {
32934
32938
const parent = node.parent;
32935
32939
return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
32940
+ isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
32936
32941
(isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
32937
32942
(isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
32938
32943
}
@@ -33145,7 +33150,14 @@ namespace ts {
33145
33150
}
33146
33151
33147
33152
function getQuickTypeOfExpression(node: Expression) {
33148
- const expr = skipParentheses(node);
33153
+ let expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
33154
+ if (isJSDocTypeAssertion(expr)) {
33155
+ const type = getJSDocTypeAssertionType(expr);
33156
+ if (!isConstTypeReference(type)) {
33157
+ return getTypeFromTypeNode(type);
33158
+ }
33159
+ }
33160
+ expr = skipParentheses(node);
33149
33161
// Optimize for the common case of a call to a function with a single non-generic call
33150
33162
// signature where we can just fetch the return type without checking the arguments.
33151
33163
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33232,9 +33244,9 @@ namespace ts {
33232
33244
}
33233
33245
33234
33246
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
33235
- const tag = isInJSFile(node) ? getJSDocTypeTag (node) : undefined;
33236
- if (tag) {
33237
- return checkAssertionWorker(tag.typeExpression. type, tag.typeExpression. type, node.expression, checkMode);
33247
+ if (isJSDocTypeAssertion (node)) {
33248
+ const type = getJSDocTypeAssertionType(node);
33249
+ return checkAssertionWorker(type, type, node.expression, checkMode);
33238
33250
}
33239
33251
return checkExpression(node.expression, checkMode);
33240
33252
}
@@ -36184,7 +36196,7 @@ namespace ts {
36184
36196
if (getFalsyFlags(type)) return;
36185
36197
36186
36198
const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
36187
- if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses( location.expression) )) {
36199
+ if (isPropertyAccessExpression(location) && isTypeAssertion( location.expression)) {
36188
36200
return;
36189
36201
}
36190
36202
0 commit comments