@@ -8388,12 +8388,12 @@ namespace ts {
83888388 }
83898389
83908390 function isNullOrUndefined(node: Expression) {
8391- const expr = skipParentheses(node);
8391+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
83928392 return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol;
83938393 }
83948394
83958395 function isEmptyArrayLiteral(node: Expression) {
8396- const expr = skipParentheses(node);
8396+ const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true );
83978397 return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
83988398 }
83998399
@@ -22956,7 +22956,7 @@ namespace ts {
2295622956 }
2295722957
2295822958 function isFalseExpression(expr: Expression): boolean {
22959- const node = skipParentheses(expr);
22959+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2296022960 return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
2296122961 (node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
2296222962 (node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23278,7 +23278,7 @@ namespace ts {
2327823278 }
2327923279
2328023280 function narrowTypeByAssertion(type: Type, expr: Expression): Type {
23281- const node = skipParentheses(expr);
23281+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2328223282 if (node.kind === SyntaxKind.FalseKeyword) {
2328323283 return unreachableNeverType;
2328423284 }
@@ -25858,7 +25858,9 @@ namespace ts {
2585825858 case SyntaxKind.ParenthesizedExpression: {
2585925859 // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
2586025860 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);
2586225864 }
2586325865 case SyntaxKind.NonNullExpression:
2586425866 return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32768,8 +32770,10 @@ namespace ts {
3276832770 }
3276932771
3277032772 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);
3277332777 }
3277432778
3277532779 function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32844,6 +32848,7 @@ namespace ts {
3284432848 function isConstContext(node: Expression): boolean {
3284532849 const parent = node.parent;
3284632850 return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
32851+ isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
3284732852 (isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
3284832853 (isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
3284932854 }
@@ -33056,7 +33061,14 @@ namespace ts {
3305633061 }
3305733062
3305833063 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);
3306033072 // Optimize for the common case of a call to a function with a single non-generic call
3306133073 // signature where we can just fetch the return type without checking the arguments.
3306233074 if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33143,9 +33155,9 @@ namespace ts {
3314333155 }
3314433156
3314533157 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);
3314933161 }
3315033162 return checkExpression(node.expression, checkMode);
3315133163 }
@@ -36093,7 +36105,7 @@ namespace ts {
3609336105 if (getFalsyFlags(type)) return;
3609436106
3609536107 const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
36096- if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses( location.expression) )) {
36108+ if (isPropertyAccessExpression(location) && isTypeAssertion( location.expression)) {
3609736109 return;
3609836110 }
3609936111
0 commit comments