@@ -274,6 +274,7 @@ import {
274274 getJSDocHost,
275275 getJSDocParameterTags,
276276 getJSDocRoot,
277+ getJSDocSatisfiesExpressionType,
277278 getJSDocTags,
278279 getJSDocThisTag,
279280 getJSDocType,
@@ -338,8 +339,8 @@ import {
338339 hasAccessorModifier,
339340 hasAmbientModifier,
340341 hasContextSensitiveParameters,
341- HasDecorators,
342342 hasDecorators,
343+ HasDecorators,
343344 hasDynamicName,
344345 hasEffectiveModifier,
345346 hasEffectiveModifiers,
@@ -348,8 +349,8 @@ import {
348349 hasExtension,
349350 HasIllegalDecorators,
350351 HasIllegalModifiers,
351- HasInitializer,
352352 hasInitializer,
353+ HasInitializer,
353354 hasJSDocNodes,
354355 hasJSDocParameterTags,
355356 hasJsonModuleEmitEnabled,
@@ -539,6 +540,7 @@ import {
539540 isJSDocParameterTag,
540541 isJSDocPropertyLikeTag,
541542 isJSDocReturnTag,
543+ isJSDocSatisfiesExpression,
542544 isJSDocSignature,
543545 isJSDocTemplateTag,
544546 isJSDocTypeAlias,
@@ -713,6 +715,7 @@ import {
713715 JSDocPropertyTag,
714716 JSDocProtectedTag,
715717 JSDocPublicTag,
718+ JSDocSatisfiesTag,
716719 JSDocSignature,
717720 JSDocTemplateTag,
718721 JSDocTypedefTag,
@@ -28682,6 +28685,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2868228685 Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression);
2868328686 return getContextualTypeForSubstitutionExpression(parent.parent as TemplateExpression, node);
2868428687 case SyntaxKind.ParenthesizedExpression: {
28688+ if (isJSDocSatisfiesExpression(parent)) {
28689+ return getTypeFromTypeNode(getJSDocSatisfiesExpressionType(parent));
28690+ }
2868528691 // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
2868628692 const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
2868728693 return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) :
@@ -33674,15 +33680,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3367433680
3367533681 function checkSatisfiesExpression(node: SatisfiesExpression) {
3367633682 checkSourceElement(node.type);
33677- const exprType = checkExpression(node.expression);
33683+ return checkSatisfiesExpressionWorker(node.expression, node.type);
33684+ }
3367833685
33679- const targetType = getTypeFromTypeNode(node.type);
33686+ function checkSatisfiesExpressionWorker(expression: Expression, target: TypeNode, checkMode?: CheckMode) {
33687+ const exprType = checkExpression(expression, checkMode);
33688+ const targetType = getTypeFromTypeNode(target);
3368033689 if (isErrorType(targetType)) {
3368133690 return targetType;
3368233691 }
33683-
33684- checkTypeAssignableToAndOptionallyElaborate(exprType, targetType, node.type, node.expression, Diagnostics.Type_0_does_not_satisfy_the_expected_type_1);
33685-
33692+ checkTypeAssignableToAndOptionallyElaborate(exprType, targetType, target, expression, Diagnostics.Type_0_does_not_satisfy_the_expected_type_1);
3368633693 return exprType;
3368733694 }
3368833695
@@ -36406,9 +36413,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3640636413 }
3640736414
3640836415 function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
36409- if (hasJSDocNodes(node) && isJSDocTypeAssertion(node)) {
36410- const type = getJSDocTypeAssertionType(node);
36411- return checkAssertionWorker(type, type, node.expression, checkMode);
36416+ if (hasJSDocNodes(node)) {
36417+ if (isJSDocSatisfiesExpression(node)) {
36418+ return checkSatisfiesExpressionWorker(node.expression, getJSDocSatisfiesExpressionType(node), checkMode);
36419+ }
36420+ if (isJSDocTypeAssertion(node)) {
36421+ const type = getJSDocTypeAssertionType(node);
36422+ return checkAssertionWorker(type, type, node.expression, checkMode);
36423+ }
3641236424 }
3641336425 return checkExpression(node.expression, checkMode);
3641436426 }
@@ -38632,6 +38644,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3863238644 checkSourceElement(node.typeExpression);
3863338645 }
3863438646
38647+ function checkJSDocSatisfiesTag(node: JSDocSatisfiesTag) {
38648+ checkSourceElement(node.typeExpression);
38649+ }
38650+
3863538651 function checkJSDocLinkLikeTag(node: JSDocLink | JSDocLinkCode | JSDocLinkPlain) {
3863638652 if (node.name) {
3863738653 resolveJSDocMemberName(node.name, /*ignoreErrors*/ true);
@@ -43138,6 +43154,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4313843154 case SyntaxKind.JSDocProtectedTag:
4313943155 case SyntaxKind.JSDocPrivateTag:
4314043156 return checkJSDocAccessibilityModifiers(node as JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag);
43157+ case SyntaxKind.JSDocSatisfiesTag:
43158+ return checkJSDocSatisfiesTag(node as JSDocSatisfiesTag);
4314143159 case SyntaxKind.IndexedAccessType:
4314243160 return checkIndexedAccessType(node as IndexedAccessTypeNode);
4314343161 case SyntaxKind.MappedType:
0 commit comments