@@ -763,6 +763,7 @@ import {
763763 JSDocSatisfiesTag,
764764 JSDocSignature,
765765 JSDocTemplateTag,
766+ JSDocTypeAssertion,
766767 JSDocTypedefTag,
767768 JSDocTypeExpression,
768769 JSDocTypeLiteral,
@@ -1039,7 +1040,6 @@ import {
10391040 TypeReferenceSerializationKind,
10401041 TypeReferenceType,
10411042 TypeVariable,
1042- UnaryExpression,
10431043 unescapeLeadingUnderscores,
10441044 UnionOrIntersectionType,
10451045 UnionOrIntersectionTypeNode,
@@ -34358,14 +34358,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3435834358 return getReturnTypeOfSignature(signature);
3435934359 }
3436034360
34361- function checkAssertion(node: AssertionExpression) {
34361+ function checkAssertion(node: AssertionExpression, checkMode: CheckMode | undefined ) {
3436234362 if (node.kind === SyntaxKind.TypeAssertionExpression) {
3436334363 const file = getSourceFileOfNode(node);
3436434364 if (file && fileExtensionIsOneOf(file.fileName, [Extension.Cts, Extension.Mts])) {
3436534365 grammarErrorOnNode(node, Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead);
3436634366 }
3436734367 }
34368- return checkAssertionWorker(node, node.type, node.expression );
34368+ return checkAssertionWorker(node, checkMode );
3436934369 }
3437034370
3437134371 function isValidConstAssertionArgument(node: Node): boolean {
@@ -34396,16 +34396,42 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3439634396 return false;
3439734397 }
3439834398
34399- function checkAssertionWorker(errNode: Node, type: TypeNode, expression: UnaryExpression | Expression, checkMode?: CheckMode) {
34400- let exprType = checkExpression(expression, checkMode);
34399+ function checkAssertionWorker(node: JSDocTypeAssertion | AssertionExpression, checkMode: CheckMode | undefined) {
34400+ const { type, expression } = getAssertionTypeAndExpression(node);
34401+ const exprType = checkExpression(expression, checkMode);
3440134402 if (isConstTypeReference(type)) {
3440234403 if (!isValidConstAssertionArgument(expression)) {
3440334404 error(expression, Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals);
3440434405 }
3440534406 return getRegularTypeOfLiteralType(exprType);
3440634407 }
3440734408 checkSourceElement(type);
34408- exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(exprType));
34409+ checkNodeDeferred(node);
34410+ return getTypeFromTypeNode(type);
34411+ }
34412+
34413+ function getAssertionTypeAndExpression(node: JSDocTypeAssertion | AssertionExpression) {
34414+ let type: TypeNode;
34415+ let expression: Expression;
34416+ switch (node.kind) {
34417+ case SyntaxKind.AsExpression:
34418+ case SyntaxKind.TypeAssertionExpression:
34419+ type = node.type;
34420+ expression = node.expression;
34421+ break;
34422+ case SyntaxKind.ParenthesizedExpression:
34423+ type = getJSDocTypeAssertionType(node);
34424+ expression = node.expression;
34425+ break;
34426+ }
34427+
34428+ return { type, expression };
34429+ }
34430+
34431+ function checkAssertionDeferred(node: JSDocTypeAssertion | AssertionExpression) {
34432+ const { type, expression } = getAssertionTypeAndExpression(node);
34433+ const errNode = isParenthesizedExpression(node) ? type : node;
34434+ const exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression)));
3440934435 const targetType = getTypeFromTypeNode(type);
3441034436 if (!isErrorType(targetType)) {
3441134437 addLazyDiagnostic(() => {
@@ -34416,7 +34442,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3441634442 }
3441734443 });
3441834444 }
34419- return targetType;
3442034445 }
3442134446
3442234447 function checkNonNullChain(node: NonNullChain) {
@@ -37662,8 +37687,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3766237687 return checkSatisfiesExpressionWorker(node.expression, getJSDocSatisfiesExpressionType(node), checkMode);
3766337688 }
3766437689 if (isJSDocTypeAssertion(node)) {
37665- const type = getJSDocTypeAssertionType(node);
37666- return checkAssertionWorker(type, type, node.expression, checkMode);
37690+ return checkAssertionWorker(node, checkMode);
3766737691 }
3766837692 }
3766937693 return checkExpression(node.expression, checkMode);
@@ -37744,7 +37768,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3774437768 return checkTypeOfExpression(node as TypeOfExpression);
3774537769 case SyntaxKind.TypeAssertionExpression:
3774637770 case SyntaxKind.AsExpression:
37747- return checkAssertion(node as AssertionExpression);
37771+ return checkAssertion(node as AssertionExpression, checkMode );
3774837772 case SyntaxKind.NonNullExpression:
3774937773 return checkNonNullAssertion(node as NonNullExpression);
3775037774 case SyntaxKind.ExpressionWithTypeArguments:
@@ -44848,6 +44872,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4484844872 case SyntaxKind.JsxElement:
4484944873 checkJsxElementDeferred(node as JsxElement);
4485044874 break;
44875+ case SyntaxKind.TypeAssertionExpression:
44876+ case SyntaxKind.AsExpression:
44877+ case SyntaxKind.ParenthesizedExpression:
44878+ checkAssertionDeferred(node as AssertionExpression | JSDocTypeAssertion);
4485144879 }
4485244880 currentNode = saveCurrentNode;
4485344881 tracing?.pop();
0 commit comments