diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index ffe50784b6..bbbd375674 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -801,8 +801,9 @@ const ( OEKNonNullAssertions OuterExpressionKinds = 1 << 2 OEKPartiallyEmittedExpressions OuterExpressionKinds = 1 << 3 OEKExpressionsWithTypeArguments OuterExpressionKinds = 1 << 4 - OEKExcludeJSDocTypeAssertion = 1 << 5 - OEKAssertions = OEKTypeAssertions | OEKNonNullAssertions + OEKSatisfies OuterExpressionKinds = 1 << 5 + OEKExcludeJSDocTypeAssertion = 1 << 6 + OEKAssertions = OEKTypeAssertions | OEKNonNullAssertions | OEKSatisfies OEKAll = OEKParentheses | OEKAssertions | OEKPartiallyEmittedExpressions | OEKExpressionsWithTypeArguments ) @@ -811,8 +812,10 @@ func IsOuterExpression(node *Expression, kinds OuterExpressionKinds) bool { switch node.Kind { case KindParenthesizedExpression: return kinds&OEKParentheses != 0 && !(kinds&OEKExcludeJSDocTypeAssertion != 0 && isJSDocTypeAssertion(node)) - case KindTypeAssertionExpression, KindAsExpression, KindSatisfiesExpression: + case KindTypeAssertionExpression, KindAsExpression: return kinds&OEKTypeAssertions != 0 + case KindSatisfiesExpression: + return kinds&(OEKExpressionsWithTypeArguments|OEKSatisfies) != 0 case KindExpressionWithTypeArguments: return kinds&OEKExpressionsWithTypeArguments != 0 case KindNonNullExpression: diff --git a/internal/checker/checker.go b/internal/checker/checker.go index dd0e3b41d2..7205428fc0 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -9024,11 +9024,12 @@ func (c *Checker) getThisArgumentType(node *ast.Node) *Type { } func (c *Checker) getEffectiveCheckNode(argument *ast.Node) *ast.Node { - argument = ast.SkipParentheses(argument) - if ast.IsSatisfiesExpression(argument) { - return ast.SkipParentheses(argument.Expression()) - } - return argument + flags := core.IfElse( + ast.IsInJSFile(argument), + ast.OEKParentheses|ast.OEKSatisfies|ast.OEKExcludeJSDocTypeAssertion, + ast.OEKParentheses|ast.OEKSatisfies, + ) + return ast.SkipOuterExpressions(argument, flags) } func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args []*ast.Node, checkMode CheckMode, context *InferenceContext) []*Type { diff --git a/internal/transformers/typeeraser.go b/internal/transformers/typeeraser.go index a5857898ef..aa39d06db7 100644 --- a/internal/transformers/typeeraser.go +++ b/internal/transformers/typeeraser.go @@ -230,7 +230,7 @@ func (tx *TypeEraserTransformer) visit(node *ast.Node) *ast.Node { case ast.KindParenthesizedExpression: n := node.AsParenthesizedExpression() - expression := ast.SkipOuterExpressions(n.Expression, ^(ast.OEKTypeAssertions | ast.OEKExpressionsWithTypeArguments)) + expression := ast.SkipOuterExpressions(n.Expression, ^(ast.OEKAssertions | ast.OEKExpressionsWithTypeArguments)) if ast.IsAssertionExpression(expression) || ast.IsSatisfiesExpression(expression) { partial := tx.factory.NewPartiallyEmittedExpression(tx.visitor.VisitNode(n.Expression)) tx.emitContext.SetOriginal(partial, node) diff --git a/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt b/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt index 891a4f47eb..d8e8d6f82f 100644 --- a/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt +++ b/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt @@ -28,8 +28,8 @@ typeSatisfaction_errorLocations1.ts(47,24): error TS2322: Type 'number' is not a typeSatisfaction_errorLocations1.ts(48,21): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'. Types of property 'a' are incompatible. Type 'number' is not assignable to type 'true'. -typeSatisfaction_errorLocations1.ts(50,27): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. -typeSatisfaction_errorLocations1.ts(51,28): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(50,23): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. ==== typeSatisfaction_errorLocations1.ts (24 errors) ==== @@ -141,11 +141,11 @@ typeSatisfaction_errorLocations1.ts(51,28): error TS2741: Property 'a' is missin !!! error TS2322: Type 'number' is not assignable to type 'true'. ((): { a: true } => (({}) satisfies unknown) satisfies unknown)(); - ~~~~~~~~~ + ~~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. !!! related TS2728 typeSatisfaction_errorLocations1.ts:50:8: 'a' is declared here. ((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)(); - ~~~~~~~~~ + ~~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. !!! related TS2728 typeSatisfaction_errorLocations1.ts:51:8: 'a' is declared here. \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt.diff index 01b27ff30f..3052aa54cb 100644 --- a/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt.diff +++ b/testdata/baselines/reference/submodule/conformance/typeSatisfaction_errorLocations1.errors.txt.diff @@ -24,18 +24,7 @@ typeSatisfaction_errorLocations1.ts(34,9): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. typeSatisfaction_errorLocations1.ts(36,9): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. typeSatisfaction_errorLocations1.ts(39,3): error TS2322: Type 'string' is not assignable to type 'number'. -@@= skipped -12, +11 lines =@@ - typeSatisfaction_errorLocations1.ts(48,21): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'. - Types of property 'a' are incompatible. - Type 'number' is not assignable to type 'true'. --typeSatisfaction_errorLocations1.ts(50,23): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. --typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. -+typeSatisfaction_errorLocations1.ts(50,27): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. -+typeSatisfaction_errorLocations1.ts(51,28): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. - - - ==== typeSatisfaction_errorLocations1.ts (24 errors) ==== -@@= skipped -10, +10 lines =@@ +@@= skipped -22, +21 lines =@@ const fn1 = (s: { a: true }) => {}; fn1({} satisfies unknown); ~~ @@ -64,18 +53,4 @@ +!!! error TS4104: The type 'readonly [10, "20"]' is 'readonly' and cannot be assigned to the mutable type 'number[]'. declare function fn4(...args: number[]): void; - fn4(10, ...(["10", "20"] satisfies readonly string[])); -@@= skipped -41, +40 lines =@@ - !!! error TS2322: Type 'number' is not assignable to type 'true'. - - ((): { a: true } => (({}) satisfies unknown) satisfies unknown)(); -- ~~ -+ ~~~~~~~~~ - !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. - !!! related TS2728 typeSatisfaction_errorLocations1.ts:50:8: 'a' is declared here. - ((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)(); -- ~~ -+ ~~~~~~~~~ - !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. - !!! related TS2728 typeSatisfaction_errorLocations1.ts:51:8: 'a' is declared here. - \ No newline at end of file + fn4(10, ...(["10", "20"] satisfies readonly string[])); \ No newline at end of file