Repository: swc-project/swc (rust)

Issue:
Typescript compilation - Assignment Assertions
### Describe the bug

When I tried to compile my application with assignment assertions swc crash. 

```
Error: error: Unexpected token `!`. Expected identifier, string literal, numeric literal or [ for the computed key
29 |     private!: boolean;
```

### Input code

```typescript
class Game {
    private!: boolean;
}
```


### Config

_No response_

### Playground link

https://play.swc.rs/?version=1.2.118&code=H4sIAAAAAAAAA0vOSSwuVnBPzE1VqOZSAIKCosyyxJJURSuF4JKizLx0rloA3sXoGiMAAAA%3D&config=H4sIAAAAAAAAA0WNSQrDMAxF76J1Fk0WXfgOPYRxlODiCUmBGuO7Vw4u3Ul%2FeL%2FBmx2YBsUSI42LaxL7AQNSC7IjXwQWEFbpsIGx62PpRNEI8vbYVrVDzoxghC5cIPrkjzpYLsdCyDyratl0BvyRFBXzfg2h3XM38gn9z5g9z68ZHBP9Cwznsdi3AAAA

### Expected behavior

That I can use Assignment Assertions in typescript class

### Version

1.2.118

### Additional context

_No response_

Pull request:
fix(ecma/parser): allow Assignment Assertions in typescript class
**Related issue (if exists):**

fix #2990 


Patch:
diff --git a/crates/swc_ecma_parser/src/parser/typescript.rs b/crates/swc_ecma_parser/src/parser/typescript.rs
index 9b60f65795..6ff1bd398a 100644
--- a/crates/swc_ecma_parser/src/parser/typescript.rs
+++ b/crates/swc_ecma_parser/src/parser/typescript.rs
@@ -20,7 +20,8 @@ impl<I: Tokens> Parser<I> {
             && !is!(self, ')')
             && !is!(self, ':')
             && !is!(self, '=')
-            && !is!(self, '?'))
+            && !is!(self, '?')
+            && !is!(self, '!'))
     }
 
     /// Parses a modifier matching one the given modifier names.


Test patch:
diff --git a/crates/swc/tests/fixture/issue-2990/1/input/.swcrc b/crates/swc/tests/fixture/issue-2990/1/input/.swcrc
new file mode 100644
index 0000000000..77ae0f6af9
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/1/input/.swcrc
@@ -0,0 +1,8 @@
+{
+    "jsc": {
+        "parser": {
+            "syntax": "typescript"
+        },
+        "target": "es2015"
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issue-2990/1/input/index.ts b/crates/swc/tests/fixture/issue-2990/1/input/index.ts
new file mode 100644
index 0000000000..eb96873608
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/1/input/index.ts
@@ -0,0 +1,3 @@
+class Game {
+    private!: boolean;
+}
diff --git a/crates/swc/tests/fixture/issue-2990/1/output/index.ts b/crates/swc/tests/fixture/issue-2990/1/output/index.ts
new file mode 100644
index 0000000000..018dc73b71
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/1/output/index.ts
@@ -0,0 +1,2 @@
+class Game {
+}
diff --git a/crates/swc/tests/fixture/issue-2990/2/input/.swcrc b/crates/swc/tests/fixture/issue-2990/2/input/.swcrc
new file mode 100644
index 0000000000..77ae0f6af9
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/2/input/.swcrc
@@ -0,0 +1,8 @@
+{
+    "jsc": {
+        "parser": {
+            "syntax": "typescript"
+        },
+        "target": "es2015"
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issue-2990/2/input/index.ts b/crates/swc/tests/fixture/issue-2990/2/input/index.ts
new file mode 100644
index 0000000000..3865f50418
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/2/input/index.ts
@@ -0,0 +1,9 @@
+class Foo {
+    public!: unknown;
+    protected!: unknown;
+    private!: unknown;
+    abstract!: unknown;
+    readonly!: unknown;
+    override!: unknown;
+    static!: unknown;
+}
diff --git a/crates/swc/tests/fixture/issue-2990/2/output/index.ts b/crates/swc/tests/fixture/issue-2990/2/output/index.ts
new file mode 100644
index 0000000000..f230fa0f41
--- /dev/null
+++ b/crates/swc/tests/fixture/issue-2990/2/output/index.ts
@@ -0,0 +1,2 @@
+class Foo {
+}
diff --git a/crates/swc_ecma_parser/tests/typescript/issue-1514/case1/input.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-1514/case1/input.ts.json
index 28719e7904..5e4394694d 100644
--- a/crates/swc_ecma_parser/tests/typescript/issue-1514/case1/input.ts.json
+++ b/crates/swc_ecma_parser/tests/typescript/issue-1514/case1/input.ts.json
@@ -74,7 +74,7 @@
             "isAbstract": false,
             "isOptional": false,
             "isOverride": false,
-            "readonly": true,
+            "readonly": false,
             "declare": false,
             "definite": true
           }