Repository: swc-project/swc (rust)

Issue:
Fails parsing `type satisfies = 0;`
### Describe the bug

/

### Input code

```typescript
type satisfies = 0;
```
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false
    },
    "target": "es5",
    "loose": false,
    "minify": {
      "compress": false,
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.3.92&code=H4sIAAAAAAAAAyupLEhVKE4sySxOy0wtVrBVMLAGAFY5CaATAAAA&config=H4sIAAAAAAAAA1WPSw7DIAwF9zkF8rrbdtE79BCIOhERP9mOVBTl7oUE0maH3xszsA5KwcwGnmotxzIkTYx0ziXhHER%2FSgKSE7IhmwRuvRWu1agd4x5tRwOiaUKpW8j3hoOLkbHjLfM22DH%2FC030iZD5ClZUh8nhVTc0Jfj4XvayfaQ%2B9tA%2F4Ad12XkxWH71TaEFh%2B0LYuVI0xQBAAA%3D

### SWC Info output

_No response_

### Expected behavior

It should parse it as a type declaration: https://www.typescriptlang.org/play?#code/C4TwDgpgBAzghsAljAZoiMoF4oAYDcQA

### Actual behavior

It tries to parse it as a "satisfies" type operator and fails

### Version

1.3.92

### Additional context

https://github.com/babel/babel/issues/16048

Pull request:
fix(es/parsing): Fix parsing of `type satisfies = 0;`
**Related issue:**

 - Closes #8121

Patch:
diff --git a/crates/swc_ecma_parser/src/parser/stmt.rs b/crates/swc_ecma_parser/src/parser/stmt.rs
index d72fc67e31..ddfb6bf785 100644
--- a/crates/swc_ecma_parser/src/parser/stmt.rs
+++ b/crates/swc_ecma_parser/src/parser/stmt.rs
@@ -336,6 +336,19 @@ impl<'a, I: Tokens> Parser<I> {
                 }
             }
 
+            tok!("type") => {
+                if is_typescript
+                    && peeked_is!(self, IdentName)
+                    && !self.input.has_linebreak_between_cur_and_peeked()
+                {
+                    let start = self.input.cur_pos();
+                    bump!(self);
+                    return Ok(Stmt::Decl(Decl::TsTypeAlias(
+                        self.parse_ts_type_alias_decl(start)?,
+                    )));
+                }
+            }
+
             tok!("enum") => {
                 if is_typescript
                     && peeked_is!(self, IdentName)
diff --git a/crates/swc_ecma_parser/src/parser/typescript.rs b/crates/swc_ecma_parser/src/parser/typescript.rs
index 808de93c56..d41953dc11 100644
--- a/crates/swc_ecma_parser/src/parser/typescript.rs
+++ b/crates/swc_ecma_parser/src/parser/typescript.rs
@@ -1113,7 +1113,10 @@ impl<I: Tokens> Parser<I> {
     }
 
     /// `tsParseTypeAliasDeclaration`
-    fn parse_ts_type_alias_decl(&mut self, start: BytePos) -> PResult<Box<TsTypeAliasDecl>> {
+    pub(super) fn parse_ts_type_alias_decl(
+        &mut self,
+        start: BytePos,
+    ) -> PResult<Box<TsTypeAliasDecl>> {
         debug_assert!(self.input.syntax().typescript());
 
         let id = self.parse_ident_name()?;


Test patch:
diff --git a/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts b/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts
new file mode 100644
index 0000000000..7e40da6241
--- /dev/null
+++ b/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts
@@ -0,0 +1,1 @@
+type satisfies = 0;
\ No newline at end of file
diff --git a/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts.json
new file mode 100644
index 0000000000..8c2af5a3c9
--- /dev/null
+++ b/crates/swc_ecma_parser/tests/typescript/issue-8121/input.ts.json
@@ -0,0 +1,49 @@
+{
+  "type": "Script",
+  "span": {
+    "start": 1,
+    "end": 20,
+    "ctxt": 0
+  },
+  "body": [
+    {
+      "type": "TsTypeAliasDeclaration",
+      "span": {
+        "start": 1,
+        "end": 20,
+        "ctxt": 0
+      },
+      "declare": false,
+      "id": {
+        "type": "Identifier",
+        "span": {
+          "start": 6,
+          "end": 15,
+          "ctxt": 0
+        },
+        "value": "satisfies",
+        "optional": false
+      },
+      "typeParams": null,
+      "typeAnnotation": {
+        "type": "TsLiteralType",
+        "span": {
+          "start": 18,
+          "end": 19,
+          "ctxt": 0
+        },
+        "literal": {
+          "type": "NumericLiteral",
+          "span": {
+            "start": 18,
+            "end": 19,
+            "ctxt": 0
+          },
+          "value": 0.0,
+          "raw": "0"
+        }
+      }
+    }
+  ],
+  "interpreter": null
+}