@@ -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
@@ -11800,7 +11800,7 @@ namespace ts {
1180011800 // Flags we want to propagate to the result if they exist in all source symbols
1180111801 let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
1180211802 let syntheticFlag = CheckFlags.SyntheticMethod;
11803- let checkFlags = 0 ;
11803+ let checkFlags = isUnion ? 0 : CheckFlags.Readonly ;
1180411804 let mergedInstantiations = false;
1180511805 for (const current of containingType.types) {
1180611806 const type = getApparentType(current);
@@ -11839,8 +11839,13 @@ namespace ts {
1183911839 }
1184011840 }
1184111841 }
11842- checkFlags |= (isReadonlySymbol(prop) ? CheckFlags.Readonly : 0) |
11843- (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
11842+ if (isUnion && isReadonlySymbol(prop)) {
11843+ checkFlags |= CheckFlags.Readonly;
11844+ }
11845+ else if (!isUnion && !isReadonlySymbol(prop)) {
11846+ checkFlags &= ~CheckFlags.Readonly;
11847+ }
11848+ checkFlags |= (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
1184411849 (modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) |
1184511850 (modifiers & ModifierFlags.Private ? CheckFlags.ContainsPrivate : 0) |
1184611851 (modifiers & ModifierFlags.Static ? CheckFlags.ContainsStatic : 0);
@@ -22966,7 +22971,7 @@ namespace ts {
2296622971 }
2296722972
2296822973 function isFalseExpression(expr: Expression): boolean {
22969- const node = skipParentheses(expr);
22974+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2297022975 return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
2297122976 (node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
2297222977 (node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23288,7 +23293,7 @@ namespace ts {
2328823293 }
2328923294
2329023295 function narrowTypeByAssertion(type: Type, expr: Expression): Type {
23291- const node = skipParentheses(expr);
23296+ const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true );
2329223297 if (node.kind === SyntaxKind.FalseKeyword) {
2329323298 return unreachableNeverType;
2329423299 }
@@ -25872,7 +25877,9 @@ namespace ts {
2587225877 case SyntaxKind.ParenthesizedExpression: {
2587325878 // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
2587425879 const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
25875- return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent as ParenthesizedExpression, contextFlags);
25880+ return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) :
25881+ isJSDocTypeTag(tag) && isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ParenthesizedExpression) :
25882+ getTypeFromTypeNode(tag.typeExpression.type);
2587625883 }
2587725884 case SyntaxKind.NonNullExpression:
2587825885 return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32855,8 +32862,10 @@ namespace ts {
3285532862 }
3285632863
3285732864 function isTypeAssertion(node: Expression) {
32858- node = skipParentheses(node);
32859- return node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression;
32865+ node = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
32866+ return node.kind === SyntaxKind.TypeAssertionExpression ||
32867+ node.kind === SyntaxKind.AsExpression ||
32868+ isJSDocTypeAssertion(node);
3286032869 }
3286132870
3286232871 function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32931,6 +32940,7 @@ namespace ts {
3293132940 function isConstContext(node: Expression): boolean {
3293232941 const parent = node.parent;
3293332942 return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
32943+ isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
3293432944 (isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
3293532945 (isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
3293632946 }
@@ -33143,7 +33153,14 @@ namespace ts {
3314333153 }
3314433154
3314533155 function getQuickTypeOfExpression(node: Expression) {
33146- const expr = skipParentheses(node);
33156+ let expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
33157+ if (isJSDocTypeAssertion(expr)) {
33158+ const type = getJSDocTypeAssertionType(expr);
33159+ if (!isConstTypeReference(type)) {
33160+ return getTypeFromTypeNode(type);
33161+ }
33162+ }
33163+ expr = skipParentheses(node);
3314733164 // Optimize for the common case of a call to a function with a single non-generic call
3314833165 // signature where we can just fetch the return type without checking the arguments.
3314933166 if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33230,9 +33247,9 @@ namespace ts {
3323033247 }
3323133248
3323233249 function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
33233- const tag = isInJSFile(node) ? getJSDocTypeTag (node) : undefined;
33234- if (tag) {
33235- return checkAssertionWorker(tag.typeExpression. type, tag.typeExpression. type, node.expression, checkMode);
33250+ if (isJSDocTypeAssertion (node)) {
33251+ const type = getJSDocTypeAssertionType(node);
33252+ return checkAssertionWorker(type, type, node.expression, checkMode);
3323633253 }
3323733254 return checkExpression(node.expression, checkMode);
3323833255 }
@@ -36182,7 +36199,7 @@ namespace ts {
3618236199 if (getFalsyFlags(type)) return;
3618336200
3618436201 const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
36185- if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses( location.expression) )) {
36202+ if (isPropertyAccessExpression(location) && isTypeAssertion( location.expression)) {
3618636203 return;
3618736204 }
3618836205
0 commit comments