@@ -8402,12 +8402,12 @@ namespace ts {
84028402 }
84038403
84048404 function isNullOrUndefined(node: Expression) {
8405- const expr = skipParentheses(node);
8405+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
84068406 return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol;
84078407 }
84088408
84098409 function isEmptyArrayLiteral(node: Expression) {
8410- const expr = skipParentheses(node);
8410+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
84118411 return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
84128412 }
84138413
@@ -22968,7 +22968,7 @@ namespace ts {
2296822968 }
2296922969
2297022970 function isFalseExpression(expr: Expression): boolean {
22971- const node = skipParentheses(expr);
22971+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2297222972 return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
2297322973 (node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
2297422974 (node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23290,7 +23290,7 @@ namespace ts {
2329023290 }
2329123291
2329223292 function narrowTypeByAssertion(type: Type, expr: Expression): Type {
23293- const node = skipParentheses(expr);
23293+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2329423294 if (node.kind === SyntaxKind.FalseKeyword) {
2329523295 return unreachableNeverType;
2329623296 }
@@ -25874,7 +25874,9 @@ namespace ts {
2587425874 case SyntaxKind.ParenthesizedExpression: {
2587525875 // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
2587625876 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);
2587825880 }
2587925881 case SyntaxKind.NonNullExpression:
2588025882 return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32857,8 +32859,10 @@ namespace ts {
3285732859 }
3285832860
3285932861 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);
3286232866 }
3286332867
3286432868 function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32933,6 +32937,7 @@ namespace ts {
3293332937 function isConstContext(node: Expression): boolean {
3293432938 const parent = node.parent;
3293532939 return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
32940+ isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
3293632941 (isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
3293732942 (isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
3293832943 }
@@ -33145,7 +33150,14 @@ namespace ts {
3314533150 }
3314633151
3314733152 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);
3314933161 // Optimize for the common case of a call to a function with a single non-generic call
3315033162 // signature where we can just fetch the return type without checking the arguments.
3315133163 if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33232,9 +33244,9 @@ namespace ts {
3323233244 }
3323333245
3323433246 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);
3323833250 }
3323933251 return checkExpression(node.expression, checkMode);
3324033252 }
@@ -36184,7 +36196,7 @@ namespace ts {
3618436196 if (getFalsyFlags(type)) return;
3618536197
3618636198 const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
36187- if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses( location.expression) )) {
36199+ if (isPropertyAccessExpression(location) && isTypeAssertion( location.expression)) {
3618836200 return;
3618936201 }
3619036202
0 commit comments