diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 58173d64bbc9a..4c0fc784f012e 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2269,20 +2269,13 @@ impl GenExpr for TSAsExpression<'_> { impl GenExpr for TSSatisfiesExpression<'_> { fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context) { - p.print_ascii_byte(b'('); - let should_wrap = - if let Expression::FunctionExpression(func) = &self.expression.without_parentheses() { - // pife is handled on Function side - !func.pife - } else { - true - }; - p.wrap(should_wrap, |p| { - self.expression.print_expr(p, precedence, Context::default()); + let wrap = precedence >= Precedence::Compare; + + p.wrap(wrap, |p| { + self.expression.print_expr(p, Precedence::Exponentiation, ctx); + p.print_str(" satisfies "); + self.type_annotation.print(p, ctx); }); - p.print_str(" satisfies "); - self.type_annotation.print(p, ctx); - p.print_ascii_byte(b')'); } } diff --git a/crates/oxc_codegen/tests/integration/snapshots/minify.snap b/crates/oxc_codegen/tests/integration/snapshots/minify.snap index 81ec0162866dc..08fe04b349058 100644 --- a/crates/oxc_codegen/tests/integration/snapshots/minify.snap +++ b/crates/oxc_codegen/tests/integration/snapshots/minify.snap @@ -138,7 +138,7 @@ new Map; ########## 32 d = x satisfies y; ---------- -d=((x) satisfies y); +d=x satisfies y; ########## 33 export @x declare abstract class C {} ---------- diff --git a/crates/oxc_codegen/tests/integration/snapshots/pure_comments.snap b/crates/oxc_codegen/tests/integration/snapshots/pure_comments.snap index f983711b31666..a4c6f439d1f28 100644 --- a/crates/oxc_codegen/tests/integration/snapshots/pure_comments.snap +++ b/crates/oxc_codegen/tests/integration/snapshots/pure_comments.snap @@ -451,7 +451,7 @@ const Foo = (/* @__PURE__ */ (() => {})() as unknown) as { ########## 27 const Foo = /* @__PURE__ */ (() => {})() satisfies X ---------- -const Foo = ((/* @__PURE__ */ (() => {})()) satisfies X); +const Foo = /* @__PURE__ */ (() => {})() satisfies X; ########## 28 const Foo = /* @__PURE__ */ (() => {})() @@ -466,7 +466,7 @@ const Foo = ((/* @__PURE__ */ (() => {})())!); ########## 30 const Foo = /* @__PURE__ */ (() => {})()! as X satisfies Y ---------- -const Foo = ((((/* @__PURE__ */ (() => {})())!) as X) satisfies Y); +const Foo = (((/* @__PURE__ */ (() => {})())!) as X) satisfies Y; ########## 31 /* @__NO_SIDE_EFFECTS__ */ ((options, extraOptions) => { diff --git a/crates/oxc_codegen/tests/integration/snapshots/ts.snap b/crates/oxc_codegen/tests/integration/snapshots/ts.snap index 135df4f1a7f0b..2894ca98bd16d 100644 --- a/crates/oxc_codegen/tests/integration/snapshots/ts.snap +++ b/crates/oxc_codegen/tests/integration/snapshots/ts.snap @@ -205,7 +205,7 @@ new Map(); ########## 32 d = x satisfies y; ---------- -d = ((x) satisfies y); +d = x satisfies y; ########## 33 export @x declare abstract class C {} diff --git a/crates/oxc_codegen/tests/integration/ts.rs b/crates/oxc_codegen/tests/integration/ts.rs index 148b248a61b7c..c327ef1ac667c 100644 --- a/crates/oxc_codegen/tests/integration/ts.rs +++ b/crates/oxc_codegen/tests/integration/ts.rs @@ -154,3 +154,16 @@ fn ts_as_expression_in_binary_expr() { "!(typeof that === 'object' && 'keys' in that && typeof (that as object & { keys: unknown }).keys === 'function')", ); } + +#[test] +fn ts_satisfies_expression() { + test_idempotency("d = x satisfies y"); + test_idempotency("const Foo = (() => {})() satisfies X"); + test_idempotency("const Bar = (x as Y) satisfies Z"); + test_idempotency("(x satisfies Y).foo"); + test_idempotency("(x satisfies Y)[0]"); + test_idempotency("(x satisfies Y)()"); + test_idempotency("x satisfies Y || z"); + test_idempotency("x satisfies Y && z"); + test_idempotency("x satisfies Y === z"); +}