Repository: babel/babel (TypeScript)

Issue:
[Bug]: cannot parse `satisfies` op that is in in left side of assignment
### 💻

- [ ] Would you like to work on a fix?

### How are you using Babel?

Programmatic API (`babel.transform`, `babel.parse`)

### Input code

- [Babel REPL Link](https://babeljs.io/repl#?browsers=&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=DYUwLgBAhhC8EDsCuxgG4BQAKGEDOUYAlngGZEh7QICeAlHIiuhkA&debug=false&forceAllTransforms=true&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=env%2Ctypescript&prettier=false&targets=Node-4&version=7.20.0&externalPlugins=&assumptions=%7B%7D)

```js
(a satisfies any) = null;
```

### Configuration file name

_No response_

### Configuration

Enable `typescript` plugin via `@babel/parser` API.

### Current and expected behavior

**current:**

Syntax error: `Invalid parenthesized assignment pattern. (2:1)`

**expected:**

No errors.

### Environment

```
System:
    OS: macOS 12.3
  Binaries:
    Node: 16.17.1 - ~/.volta/tools/image/node/16.17.1/bin/node
    Yarn: 3.2.4 - ~/.volta/tools/image/yarn/1.22.19/bin/yarn
    npm: 8.15.0 - ~/.volta/tools/image/node/16.17.1/bin/npm
  npmPackages:
    @babel/code-frame: 7.18.6 => 7.18.6 
    @babel/generator: 7.20.0 => 7.20.0 
    @babel/parser: 7.20.0 => 7.20.0 
    @babel/types: 7.20.0 => 7.20.0 
    eslint: 8.26.0 => 8.26.0 
    jest: 29.2.1 => 29.2.1
```

### Possible solution

_No response_

### Additional context

TypeScript compiler can parse it ([TypeScript playground Link](https://www.typescriptlang.org/play?ts=4.9.0-dev.20221025#code/BQQwBAziAuCWEDNYFMJhAOwJ4EowF4wMBXAG1IG4AoIA))



Hints:

Patch:
diff --git a/packages/babel-parser/src/plugins/typescript/index.ts b/packages/babel-parser/src/plugins/typescript/index.ts
--- a/packages/babel-parser/src/plugins/typescript/index.ts
+++ b/packages/babel-parser/src/plugins/typescript/index.ts
@@ -3540,6 +3540,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
           this.toAssignableParenthesizedExpression(node, isLHS);
           break;
         case "TSAsExpression":
+        case "TSSatisfiesExpression":
         case "TSNonNullExpression":
         case "TSTypeAssertion":
           if (isLHS) {
@@ -3565,6 +3566,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
     toAssignableParenthesizedExpression(node: N.Node, isLHS: boolean): void {
       switch (node.expression.type) {
         case "TSAsExpression":
+        case "TSSatisfiesExpression":
         case "TSNonNullExpression":
         case "TSTypeAssertion":
         case "ParenthesizedExpression":
@@ -3578,6 +3580,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
     checkToRestConversion(node: N.Node, allowPattern: boolean): void {
       switch (node.type) {
         case "TSAsExpression":
+        case "TSSatisfiesExpression":
         case "TSTypeAssertion":
         case "TSNonNullExpression":
           this.checkToRestConversion(node.expression, false);
@@ -3594,6 +3597,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
         | "TSParameterProperty"
         | "TSNonNullExpression"
         | "TSAsExpression"
+        | "TSSatisfiesExpression"
         | "TSTypeAssertion",
       isUnparenthesizedInAssign: boolean,
       binding: BindingTypes,
@@ -3609,6 +3613,8 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
             TSNonNullExpression: "expression",
             TSAsExpression: (binding !== BIND_NONE ||
               !isUnparenthesizedInAssign) && ["expression", true],
+            TSSatisfiesExpression: (binding !== BIND_NONE ||
+              !isUnparenthesizedInAssign) && ["expression", true],
             TSTypeAssertion: (binding !== BIND_NONE ||
               !isUnparenthesizedInAssign) && ["expression", true],
           },


Test patch:
diff --git a/packages/babel-parser/test/fixtures/typescript/cast/satisfies/input.ts b/packages/babel-parser/test/fixtures/typescript/cast/satisfies/input.ts
--- a/packages/babel-parser/test/fixtures/typescript/cast/satisfies/input.ts
+++ b/packages/babel-parser/test/fixtures/typescript/cast/satisfies/input.ts
@@ -1,2 +1,4 @@
 x satisfies T;
 x < y satisfies boolean; // (x < y) satisfies boolean;
+(a satisfies any) = null;
+[(a satisfies any)] = b;
diff --git a/packages/babel-parser/test/fixtures/typescript/cast/satisfies/output.json b/packages/babel-parser/test/fixtures/typescript/cast/satisfies/output.json
--- a/packages/babel-parser/test/fixtures/typescript/cast/satisfies/output.json
+++ b/packages/babel-parser/test/fixtures/typescript/cast/satisfies/output.json
@@ -1,9 +1,9 @@
 {
   "type": "File",
-  "start":0,"end":69,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":54,"index":69}},
+  "start":0,"end":120,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":4,"column":24,"index":120}},
   "program": {
     "type": "Program",
-    "start":0,"end":69,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":54,"index":69}},
+    "start":0,"end":120,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":4,"column":24,"index":120}},
     "sourceType": "module",
     "interpreter": null,
     "body": [
@@ -62,6 +62,80 @@
             "start":40,"end":69,"loc":{"start":{"line":2,"column":25,"index":40},"end":{"line":2,"column":54,"index":69}}
           }
         ]
+      },
+      {
+        "type": "ExpressionStatement",
+        "start":70,"end":95,"loc":{"start":{"line":3,"column":0,"index":70},"end":{"line":3,"column":25,"index":95}},
+        "expression": {
+          "type": "AssignmentExpression",
+          "start":70,"end":94,"loc":{"start":{"line":3,"column":0,"index":70},"end":{"line":3,"column":24,"index":94}},
+          "operator": "=",
+          "left": {
+            "type": "TSSatisfiesExpression",
+            "start":71,"end":86,"loc":{"start":{"line":3,"column":1,"index":71},"end":{"line":3,"column":16,"index":86}},
+            "expression": {
+              "type": "Identifier",
+              "start":71,"end":72,"loc":{"start":{"line":3,"column":1,"index":71},"end":{"line":3,"column":2,"index":72},"identifierName":"a"},
+              "name": "a"
+            },
+            "typeAnnotation": {
+              "type": "TSAnyKeyword",
+              "start":83,"end":86,"loc":{"start":{"line":3,"column":13,"index":83},"end":{"line":3,"column":16,"index":86}}
+            },
+            "extra": {
+              "parenthesized": true,
+              "parenStart": 70
+            }
+          },
+          "right": {
+            "type": "NullLiteral",
+            "start":90,"end":94,"loc":{"start":{"line":3,"column":20,"index":90},"end":{"line":3,"column":24,"index":94}}
+          }
+        },
+        "leadingComments": [
+          {
+            "type": "CommentLine",
+            "value": " (x < y) satisfies boolean;",
+            "start":40,"end":69,"loc":{"start":{"line":2,"column":25,"index":40},"end":{"line":2,"column":54,"index":69}}
+          }
+        ]
+      },
+      {
+        "type": "ExpressionStatement",
+        "start":96,"end":120,"loc":{"start":{"line":4,"column":0,"index":96},"end":{"line":4,"column":24,"index":120}},
+        "expression": {
+          "type": "AssignmentExpression",
+          "start":96,"end":119,"loc":{"start":{"line":4,"column":0,"index":96},"end":{"line":4,"column":23,"index":119}},
+          "operator": "=",
+          "left": {
+            "type": "ArrayPattern",
+            "start":96,"end":115,"loc":{"start":{"line":4,"column":0,"index":96},"end":{"line":4,"column":19,"index":115}},
+            "elements": [
+              {
+                "type": "TSSatisfiesExpression",
+                "start":98,"end":113,"loc":{"start":{"line":4,"column":2,"index":98},"end":{"line":4,"column":17,"index":113}},
+                "expression": {
+                  "type": "Identifier",
+                  "start":98,"end":99,"loc":{"start":{"line":4,"column":2,"index":98},"end":{"line":4,"column":3,"index":99},"identifierName":"a"},
+                  "name": "a"
+                },
+                "typeAnnotation": {
+                  "type": "TSAnyKeyword",
+                  "start":110,"end":113,"loc":{"start":{"line":4,"column":14,"index":110},"end":{"line":4,"column":17,"index":113}}
+                },
+                "extra": {
+                  "parenthesized": true,
+                  "parenStart": 97
+                }
+              }
+            ]
+          },
+          "right": {
+            "type": "Identifier",
+            "start":118,"end":119,"loc":{"start":{"line":4,"column":22,"index":118},"end":{"line":4,"column":23,"index":119},"identifierName":"b"},
+            "name": "b"
+          }
+        }
       }
     ],
     "directives": []