Repository: babel/babel (TypeScript)

Issue:
[Bug]: should parse `type A = import("mod", { with: { type: "json" }});`
### 💻

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

### How are you using Babel?

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

### Input code

```ts
type A = import("foo", {with: {type: "json"}})
```

### Configuration file name

_No response_

### Configuration

N/A

### Current and expected behavior

**Current:**

```
SyntaxError: Unexpected token, expected ")"
```

**Expected:**

Success

### Environment

```js
const { parse } = require("@babel/parser"); // 7.23.9

const code = `type A = import("foo", { with: { type: "json"} }});`;
const result = parse(code, { plugins: ["typescript", "importAttributes" ]});
```

### Possible solution

Fix the parser

### Additional context

context: https://github.com/prettier/prettier/issues/16072

TypeScript compiler can parse it([Playground link](https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UCWBbMB7ATsAFAIgDN108AaKAbwHclgALALktEibwCsBndAOzwF9+ASgBQQA))


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
@@ -566,6 +566,19 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
 
       // For compatibility to estree we cannot call parseLiteral directly here
       node.argument = super.parseExprAtom() as N.StringLiteral;
+      if (
+        this.hasPlugin("importAttributes") ||
+        this.hasPlugin("importAssertions")
+      ) {
+        node.options = null;
+      }
+      if (this.eat(tt.comma)) {
+        this.expectImportAttributesPlugin();
+        if (!this.match(tt.parenR)) {
+          node.options = super.parseMaybeAssignAllowIn();
+          this.eat(tt.comma);
+        }
+      }
       this.expect(tt.parenR);
 
       if (this.eat(tt.dot)) {
diff --git a/packages/babel-parser/src/types.d.ts b/packages/babel-parser/src/types.d.ts
--- a/packages/babel-parser/src/types.d.ts
+++ b/packages/babel-parser/src/types.d.ts
@@ -1543,6 +1543,7 @@ export interface TsImportType extends TsTypeBase {
   argument: StringLiteral;
   qualifier?: TsEntityName;
   typeParameters?: TsTypeParameterInstantiation;
+  options?: Expression | null;
 }
 
 // ================
diff --git a/packages/babel-types/src/ast-types/generated/index.ts b/packages/babel-types/src/ast-types/generated/index.ts
--- a/packages/babel-types/src/ast-types/generated/index.ts
+++ b/packages/babel-types/src/ast-types/generated/index.ts
@@ -2033,6 +2033,7 @@ export interface TSImportType extends BaseNode {
   argument: StringLiteral;
   qualifier?: TSEntityName | null;
   typeParameters?: TSTypeParameterInstantiation | null;
+  options?: Expression | null;
 }
 
 export interface TSImportEqualsDeclaration extends BaseNode {
@@ -2893,6 +2894,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3006,6 +3008,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3071,6 +3074,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3153,6 +3157,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3218,6 +3223,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSLiteralType
     | TSMethodSignature
@@ -3284,6 +3290,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3349,6 +3356,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3439,6 +3447,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSLiteralType
     | TSMethodSignature
@@ -3569,6 +3578,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3653,6 +3663,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3730,6 +3741,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -3823,6 +3835,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4084,6 +4097,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4398,6 +4412,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4657,6 +4672,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4742,6 +4758,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4923,6 +4940,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -4993,6 +5011,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5094,6 +5113,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5161,6 +5181,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5226,6 +5247,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5316,6 +5338,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5381,6 +5404,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5465,6 +5489,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5632,6 +5657,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSLiteralType
     | TSMethodSignature
@@ -5698,6 +5724,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5854,6 +5881,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -5944,6 +5972,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6009,6 +6038,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6074,6 +6104,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6139,6 +6170,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6204,6 +6236,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6284,6 +6317,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6349,6 +6383,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6452,6 +6487,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6658,6 +6694,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -6807,6 +6844,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -7130,6 +7168,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -7351,6 +7390,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -7562,6 +7602,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -7754,6 +7795,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8040,6 +8082,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8106,6 +8149,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSLiteralType
     | TSMethodSignature
@@ -8172,6 +8216,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8276,6 +8321,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8355,6 +8401,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8484,6 +8531,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8610,6 +8658,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSLiteralType
     | TSMethodSignature
@@ -8701,6 +8750,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
@@ -8845,6 +8895,7 @@ export interface ParentMaps {
     | TSEnumDeclaration
     | TSEnumMember
     | TSExportAssignment
+    | TSImportType
     | TSInstantiationExpression
     | TSMethodSignature
     | TSNonNullExpression
diff --git a/packages/babel-types/src/definitions/typescript.ts b/packages/babel-types/src/definitions/typescript.ts
--- a/packages/babel-types/src/definitions/typescript.ts
+++ b/packages/babel-types/src/definitions/typescript.ts
@@ -530,6 +530,10 @@ defineType("TSImportType", {
     argument: validateType("StringLiteral"),
     qualifier: validateOptionalType("TSEntityName"),
     typeParameters: validateOptionalType("TSTypeParameterInstantiation"),
+    options: {
+      validate: assertNodeType("Expression"),
+      optional: true,
+    },
   },
 });
 


Test patch:
diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/input.ts b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/input.ts
new file mode 100644
--- /dev/null
+++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/input.ts
@@ -0,0 +1 @@
+let x: typeof import("foo.json", <ImportOptionBagJSX type="json"/>)
diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/options.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/options.json
new file mode 100644
--- /dev/null
+++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-jsx-options/options.json
@@ -0,0 +1,8 @@
+{
+  "plugins": [
+    "typescript",
+    "jsx",
+    "importAttributes"
+  ],
+  "throws": "Unexpected token, expected \"jsxTagEnd\" (1:65)"
+}
diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/input.ts b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/input.ts
new file mode 100644
--- /dev/null
+++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/input.ts
@@ -0,0 +1 @@
+let x: typeof import('./x', { with: { type: "json" }});
diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/options.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/options.json
new file mode 100644
--- /dev/null
+++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/options.json
@@ -0,0 +1,6 @@
+{
+  "plugins": [
+    "typescript",
+    "importAttributes"
+  ]
+}
diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/output.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/output.json
new file mode 100644
--- /dev/null
+++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic-with-options/output.json
@@ -0,0 +1,96 @@
+{
+  "type": "File",
+  "start":0,"end":55,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":55,"index":55}},
+  "program": {
+    "type": "Program",
+    "start":0,"end":55,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":55,"index":55}},
+    "sourceType": "module",
+    "interpreter": null,
+    "body": [
+      {
+        "type": "VariableDeclaration",
+        "start":0,"end":55,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":55,"index":55}},
+        "declarations": [
+          {
+            "type": "VariableDeclarator",
+            "start":4,"end":54,"loc":{"start":{"line":1,"column":4,"index":4},"end":{"line":1,"column":54,"index":54}},
+            "id": {
+              "type": "Identifier",
+              "start":4,"end":54,"loc":{"start":{"line":1,"column":4,"index":4},"end":{"line":1,"column":54,"index":54},"identifierName":"x"},
+              "name": "x",
+              "typeAnnotation": {
+                "type": "TSTypeAnnotation",
+                "start":5,"end":54,"loc":{"start":{"line":1,"column":5,"index":5},"end":{"line":1,"column":54,"index":54}},
+                "typeAnnotation": {
+                  "type": "TSTypeQuery",
+                  "start":7,"end":54,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":54,"index":54}},
+                  "exprName": {
+                    "type": "TSImportType",
+                    "start":14,"end":54,"loc":{"start":{"line":1,"column":14,"index":14},"end":{"line":1,"column":54,"index":54}},
+                    "argument": {
+                      "type": "StringLiteral",
+                      "start":21,"end":26,"loc":{"start":{"line":1,"column":21,"index":21},"end":{"line":1,"column":26,"index":26}},
+                      "extra": {
+                        "rawValue": "./x",
+                        "raw": "'./x'"
+                      },
+                      "value": "./x"
+                    },
+                    "options": {
+                      "type": "ObjectExpression",
+                      "start":28,"end":53,"loc":{"start":{"line":1,"column":28,"index":28},"end":{"line":1,"column":53,"index":53}},
+                      "properties": [
+                        {
+                          "type": "ObjectProperty",
+                          "start":30,"end":52,"loc":{"start":{"line":1,"column":30,"index":30},"end":{"line":1,"column":52,"index":52}},
+                          "method": false,
+                          "key": {
+                            "type": "Identifier",
+                            "start":30,"end":34,"loc":{"start":{"line":1,"column":30,"index":30},"end":{"line":1,"column":34,"index":34},"identifierName":"with"},
+                            "name": "with"
+                          },
+                          "computed": false,
+                          "shorthand": false,
+                          "value": {
+                            "type": "ObjectExpression",
+                            "start":36,"end":52,"loc":{"start":{"line":1,"column":36,"index":36},"end":{"line":1,"column":52,"index":52}},
+                            "properties": [
+                              {
+                                "type": "ObjectProperty",
+                                "start":38,"end":50,"loc":{"start":{"line":1,"column":38,"index":38},"end":{"line":1,"column":50,"index":50}},
+                                "method": false,
+                                "key": {
+                                  "type": "Identifier",
+                                  "start":38,"end":42,"loc":{"start":{"line":1,"column":38,"index":38},"end":{"line":1,"column":42,"index":42},"identifierName":"type"},
+                                  "name": "type"
+                                },
+                                "computed": false,
+                                "shorthand": false,
+                                "value": {
+                                  "type": "StringLiteral",
+                                  "start":44,"end":50,"loc":{"start":{"line":1,"column":44,"index":44},"end":{"line":1,"column":50,"index":50}},
+                                  "extra": {
+                                    "rawValue": "json",
+                                    "raw": "\"json\""
+                                  },
+                                  "value": "json"
+                                }
+                              }
+                            ]
+                          }
+                        }
+                      ]
+                    }
+                  }
+                }
+              }
+            },
+            "init": null
+          }
+        ],
+        "kind": "let"
+      }
+    ],
+    "directives": []
+  }
+}