diff --git a/packages/babel-generator/test/fixtures/typescript/export-declaration-type/input.js b/packages/babel-generator/test/fixtures/typescript/export-declaration-type/input.js new file mode 100644 index 000000000000..1d10049665df --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/export-declaration-type/input.js @@ -0,0 +1,2 @@ +export interface A {} +export type B = string; diff --git a/packages/babel-generator/test/fixtures/typescript/export-declaration-type/output.js b/packages/babel-generator/test/fixtures/typescript/export-declaration-type/output.js new file mode 100644 index 000000000000..1d10049665df --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/export-declaration-type/output.js @@ -0,0 +1,2 @@ +export interface A {} +export type B = string; diff --git a/packages/babel-generator/test/fixtures/typescript/export-type/input.js b/packages/babel-generator/test/fixtures/typescript/export-type/input.js new file mode 100644 index 000000000000..cbf7e0f4977e --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/export-type/input.js @@ -0,0 +1,3 @@ +type A = 2; +export type { A }; +export type { B } from "./mod"; diff --git a/packages/babel-generator/test/fixtures/typescript/export-type/output.js b/packages/babel-generator/test/fixtures/typescript/export-type/output.js new file mode 100644 index 000000000000..51245b7a5ae7 --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/export-type/output.js @@ -0,0 +1,3 @@ +type A = 2; +export type { A }; +export type { B } from "./mod"; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/typescript/import-type/input.js b/packages/babel-generator/test/fixtures/typescript/import-type/input.js new file mode 100644 index 000000000000..de5f7f5fc88a --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/import-type/input.js @@ -0,0 +1,3 @@ +import type T from './mod'; +import type { A, B } from './mod'; +import type * as Types from './mod'; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/typescript/import-type/output.js b/packages/babel-generator/test/fixtures/typescript/import-type/output.js new file mode 100644 index 000000000000..de5f7f5fc88a --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/import-type/output.js @@ -0,0 +1,3 @@ +import type T from './mod'; +import type { A, B } from './mod'; +import type * as Types from './mod'; \ No newline at end of file diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 53c16cfb85cd..c184a15c7c29 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -1839,7 +1839,30 @@ export default (superClass: Class): Class => if (this.match(tt.name) && this.lookahead().type === tt.eq) { return this.tsParseImportEqualsDeclaration(node); } - return super.parseImport(node); + + if (this.eatContextual("type")) { + node.importKind = "type"; + } else { + node.importKind = "value"; + } + + const importNode = super.parseImport(node); + /*:: invariant(importNode.type !== "TSImportEqualsDeclaration") */ + + // `import type` can only be used on imports with named imports or with a + // default import - but not both + if ( + importNode.importKind === "type" && + importNode.specifiers.length > 1 && + importNode.specifiers[0].type === "ImportDefaultSpecifier" + ) { + this.raise( + importNode.start, + "A type-only import can specify a default import or named bindings, but not both.", + ); + } + + return importNode; } parseExport(node: N.Node): N.AnyExport { @@ -1862,6 +1885,13 @@ export default (superClass: Class): Class => this.semicolon(); return this.finishNode(decl, "TSNamespaceExportDeclaration"); } else { + if (this.isContextual("type") && this.lookahead().type === tt.braceL) { + this.next(); + node.exportKind = "type"; + } else { + node.exportKind = "value"; + } + return super.parseExport(node); } } @@ -2097,6 +2127,14 @@ export default (superClass: Class): Class => if (!declaration) { declaration = super.parseExportDeclaration(node); } + if ( + declaration && + (declaration.type === "TSInterfaceDeclaration" || + declaration.type === "TSTypeAliasDeclaration" || + isDeclare) + ) { + node.exportKind = "type"; + } if (declaration && isDeclare) { // Reset location to include `declare` in range diff --git a/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/input.js b/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/input.js new file mode 100644 index 000000000000..2086d067fcdf --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/input.js @@ -0,0 +1 @@ +export type from 'test'; diff --git a/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/options.json b/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/options.json new file mode 100644 index 000000000000..fa7f17816e59 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/export-extensions/default-type-with-typescript/options.json @@ -0,0 +1,5 @@ +{ + "plugins": ["exportDefaultFrom", "typescript"], + "sourceType": "module", + "throws": "Unexpected token, expected \"=\" (1:17)" +} diff --git a/packages/babel-parser/test/fixtures/experimental/export-extensions/export-with-ts/output.json b/packages/babel-parser/test/fixtures/experimental/export-extensions/export-with-ts/output.json index 912eb1b41745..740426fadfca 100644 --- a/packages/babel-parser/test/fixtures/experimental/export-extensions/export-with-ts/output.json +++ b/packages/babel-parser/test/fixtures/experimental/export-extensions/export-with-ts/output.json @@ -43,6 +43,7 @@ "column": 26 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -110,6 +111,7 @@ "column": 29 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -176,6 +178,7 @@ "column": 16 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -226,6 +229,7 @@ "column": 21 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -291,6 +295,7 @@ "column": 18 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -356,6 +361,7 @@ "column": 21 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -421,6 +427,7 @@ "column": 27 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/class/abstract-false-positive/output.json b/packages/babel-parser/test/fixtures/typescript/class/abstract-false-positive/output.json index e9716a7942b7..f7f4be716603 100644 --- a/packages/babel-parser/test/fixtures/typescript/class/abstract-false-positive/output.json +++ b/packages/babel-parser/test/fixtures/typescript/class/abstract-false-positive/output.json @@ -43,6 +43,7 @@ "column": 24 } }, + "exportKind": "value", "declaration": { "type": "Identifier", "start": 78, diff --git a/packages/babel-parser/test/fixtures/typescript/class/abstract/output.json b/packages/babel-parser/test/fixtures/typescript/class/abstract/output.json index 779c334d8f43..50d59f6e6383 100644 --- a/packages/babel-parser/test/fixtures/typescript/class/abstract/output.json +++ b/packages/babel-parser/test/fixtures/typescript/class/abstract/output.json @@ -144,6 +144,7 @@ "column": 27 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -229,6 +230,7 @@ "column": 33 } }, + "exportKind": "value", "declaration": { "type": "ClassDeclaration", "start": 148, @@ -296,6 +298,7 @@ "column": 36 } }, + "exportKind": "value", "declaration": { "type": "ClassDeclaration", "start": 182, diff --git a/packages/babel-parser/test/fixtures/typescript/enum/export-const/output.json b/packages/babel-parser/test/fixtures/typescript/enum/export-const/output.json index f897f84f6293..f0db16702d27 100644 --- a/packages/babel-parser/test/fixtures/typescript/enum/export-const/output.json +++ b/packages/babel-parser/test/fixtures/typescript/enum/export-const/output.json @@ -43,6 +43,7 @@ "column": 22 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/enum/export-declare-const/output.json b/packages/babel-parser/test/fixtures/typescript/enum/export-declare-const/output.json index d0a529fa2711..1e2557b5aa66 100644 --- a/packages/babel-parser/test/fixtures/typescript/enum/export-declare-const/output.json +++ b/packages/babel-parser/test/fixtures/typescript/enum/export-declare-const/output.json @@ -43,6 +43,7 @@ "column": 30 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/enum/export/output.json b/packages/babel-parser/test/fixtures/typescript/enum/export/output.json index d78f0c7187e1..883c7397ecaf 100644 --- a/packages/babel-parser/test/fixtures/typescript/enum/export/output.json +++ b/packages/babel-parser/test/fixtures/typescript/enum/export/output.json @@ -43,6 +43,7 @@ "column": 16 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/export/declare/output.json b/packages/babel-parser/test/fixtures/typescript/export/declare/output.json index bd75590c3bd1..43acb3b77b28 100644 --- a/packages/babel-parser/test/fixtures/typescript/export/declare/output.json +++ b/packages/babel-parser/test/fixtures/typescript/export/declare/output.json @@ -43,6 +43,7 @@ "column": 31 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -142,6 +143,7 @@ "column": 34 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -225,6 +227,7 @@ "column": 25 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -292,6 +295,7 @@ "column": 29 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -358,6 +362,7 @@ "column": 31 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -423,6 +428,7 @@ "column": 26 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -489,6 +495,7 @@ "column": 29 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -555,6 +562,7 @@ "column": 26 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/input.ts b/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/input.ts new file mode 100644 index 000000000000..b8f23bbe7dd4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/input.ts @@ -0,0 +1,4 @@ +export type A = 2; +export interface B {} +export declare function a(): string; +export declare var b: string; diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/output.json b/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/output.json new file mode 100644 index 000000000000..1b6039be1525 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type-declaration/output.json @@ -0,0 +1,370 @@ +{ + "type": "File", + "start": 0, + "end": 107, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 29 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 107, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 29 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start": 0, + "end": 18, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 18 + } + }, + "exportKind": "type", + "specifiers": [], + "source": null, + "declaration": { + "type": "TSTypeAliasDeclaration", + "start": 7, + "end": 18, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + }, + "identifierName": "A" + }, + "name": "A" + }, + "typeAnnotation": { + "type": "TSLiteralType", + "start": 16, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "literal": { + "type": "NumericLiteral", + "start": 16, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + } + } + }, + { + "type": "ExportNamedDeclaration", + "start": 19, + "end": 40, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "exportKind": "type", + "specifiers": [], + "source": null, + "declaration": { + "type": "TSInterfaceDeclaration", + "start": 26, + "end": 40, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "id": { + "type": "Identifier", + "start": 36, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 18 + }, + "identifierName": "B" + }, + "name": "B" + }, + "body": { + "type": "TSInterfaceBody", + "start": 38, + "end": 40, + "loc": { + "start": { + "line": 2, + "column": 19 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "body": [] + } + } + }, + { + "type": "ExportNamedDeclaration", + "start": 41, + "end": 77, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "exportKind": "type", + "specifiers": [], + "source": null, + "declaration": { + "type": "TSDeclareFunction", + "start": 48, + "end": 77, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "id": { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 3, + "column": 24 + }, + "end": { + "line": 3, + "column": 25 + }, + "identifierName": "a" + }, + "name": "a" + }, + "generator": false, + "async": false, + "params": [], + "returnType": { + "type": "TSTypeAnnotation", + "start": 68, + "end": 76, + "loc": { + "start": { + "line": 3, + "column": 27 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "start": 70, + "end": 76, + "loc": { + "start": { + "line": 3, + "column": 29 + }, + "end": { + "line": 3, + "column": 35 + } + } + } + }, + "declare": true + } + }, + { + "type": "ExportNamedDeclaration", + "start": 78, + "end": 107, + "loc": { + "start": { + "line": 4, + "column": 0 + }, + "end": { + "line": 4, + "column": 29 + } + }, + "exportKind": "type", + "specifiers": [], + "source": null, + "declaration": { + "type": "VariableDeclaration", + "start": 85, + "end": 107, + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 4, + "column": 29 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 97, + "end": 106, + "loc": { + "start": { + "line": 4, + "column": 19 + }, + "end": { + "line": 4, + "column": 28 + } + }, + "id": { + "type": "Identifier", + "start": 97, + "end": 106, + "loc": { + "start": { + "line": 4, + "column": 19 + }, + "end": { + "line": 4, + "column": 28 + }, + "identifierName": "b" + }, + "name": "b", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 98, + "end": 106, + "loc": { + "start": { + "line": 4, + "column": 20 + }, + "end": { + "line": 4, + "column": 28 + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "start": 100, + "end": 106, + "loc": { + "start": { + "line": 4, + "column": 22 + }, + "end": { + "line": 4, + "column": 28 + } + } + } + } + }, + "init": null + } + ], + "kind": "var", + "declare": true + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type-from/input.ts b/packages/babel-parser/test/fixtures/typescript/export/export-type-from/input.ts new file mode 100644 index 000000000000..a33a1717515e --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type-from/input.ts @@ -0,0 +1 @@ +export type { T } from './mod'; diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type-from/output.json b/packages/babel-parser/test/fixtures/typescript/export/export-type-from/output.json new file mode 100644 index 000000000000..ce157bf4f047 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type-from/output.json @@ -0,0 +1,123 @@ +{ + "type": "File", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "exportKind": "type", + "specifiers": [ + { + "type": "ExportSpecifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "local": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "T" + }, + "name": "T" + }, + "exported": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "T" + }, + "name": "T" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 23, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 30 + } + }, + "extra": { + "rawValue": "./mod", + "raw": "'./mod'" + }, + "value": "./mod" + }, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type/input.ts b/packages/babel-parser/test/fixtures/typescript/export/export-type/input.ts new file mode 100644 index 000000000000..ec228e9bc1da --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type/input.ts @@ -0,0 +1,2 @@ +type A = 2; +export type { A }; diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-type/output.json b/packages/babel-parser/test/fixtures/typescript/export/export-type/output.json new file mode 100644 index 000000000000..51485202740c --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-type/output.json @@ -0,0 +1,171 @@ +{ + "type": "File", + "start": 0, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 18 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 18 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSTypeAliasDeclaration", + "start": 0, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "A" + }, + "name": "A" + }, + "typeAnnotation": { + "type": "TSLiteralType", + "start": 9, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "literal": { + "type": "NumericLiteral", + "start": 9, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + } + }, + { + "type": "ExportNamedDeclaration", + "start": 12, + "end": 30, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 18 + } + }, + "exportKind": "type", + "specifiers": [ + { + "type": "ExportSpecifier", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "local": { + "type": "Identifier", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + }, + "identifierName": "A" + }, + "name": "A" + }, + "exported": { + "type": "Identifier", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + }, + "identifierName": "A" + }, + "name": "A" + } + } + ], + "source": null, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/input.ts b/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/input.ts new file mode 100644 index 000000000000..a6aa9c5f6372 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/input.ts @@ -0,0 +1,6 @@ +export var a; +export function b() {} +export class C {} + +export enum D {} +export namespace E {} diff --git a/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/output.json b/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/output.json new file mode 100644 index 000000000000..9d7eae1f64e4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/export/export-value-declaration/output.json @@ -0,0 +1,358 @@ +{ + "type": "File", + "start": 0, + "end": 94, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 94, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "exportKind": "value", + "specifiers": [], + "source": null, + "declaration": { + "type": "VariableDeclaration", + "start": 7, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "id": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "a" + }, + "name": "a" + }, + "init": null + } + ], + "kind": "var" + } + }, + { + "type": "ExportNamedDeclaration", + "start": 14, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "exportKind": "value", + "specifiers": [], + "source": null, + "declaration": { + "type": "FunctionDeclaration", + "start": 21, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "id": { + "type": "Identifier", + "start": 30, + "end": 31, + "loc": { + "start": { + "line": 2, + "column": 16 + }, + "end": { + "line": 2, + "column": 17 + }, + "identifierName": "b" + }, + "name": "b" + }, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 34, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 20 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "body": [], + "directives": [] + } + } + }, + { + "type": "ExportNamedDeclaration", + "start": 37, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "exportKind": "value", + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start": 44, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "id": { + "type": "Identifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 3, + "column": 13 + }, + "end": { + "line": 3, + "column": 14 + }, + "identifierName": "C" + }, + "name": "C" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 52, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "body": [] + } + } + }, + { + "type": "ExportNamedDeclaration", + "start": 56, + "end": 72, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 16 + } + }, + "exportKind": "value", + "specifiers": [], + "source": null, + "declaration": { + "type": "TSEnumDeclaration", + "start": 63, + "end": 72, + "loc": { + "start": { + "line": 5, + "column": 7 + }, + "end": { + "line": 5, + "column": 16 + } + }, + "id": { + "type": "Identifier", + "start": 68, + "end": 69, + "loc": { + "start": { + "line": 5, + "column": 12 + }, + "end": { + "line": 5, + "column": 13 + }, + "identifierName": "D" + }, + "name": "D" + }, + "members": [] + } + }, + { + "type": "ExportNamedDeclaration", + "start": 73, + "end": 94, + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "exportKind": "value", + "specifiers": [], + "source": null, + "declaration": { + "type": "TSModuleDeclaration", + "start": 80, + "end": 94, + "loc": { + "start": { + "line": 6, + "column": 7 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "id": { + "type": "Identifier", + "start": 90, + "end": 91, + "loc": { + "start": { + "line": 6, + "column": 17 + }, + "end": { + "line": 6, + "column": 18 + }, + "identifierName": "E" + }, + "name": "E" + }, + "body": { + "type": "TSModuleBlock", + "start": 92, + "end": 94, + "loc": { + "start": { + "line": 6, + "column": 19 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "body": [] + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/export/nested-same-name/output.json b/packages/babel-parser/test/fixtures/typescript/export/nested-same-name/output.json index df135e3005c0..e687b30cabb8 100644 --- a/packages/babel-parser/test/fixtures/typescript/export/nested-same-name/output.json +++ b/packages/babel-parser/test/fixtures/typescript/export/nested-same-name/output.json @@ -43,6 +43,7 @@ "column": 19 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -130,6 +131,7 @@ "column": 1 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -192,6 +194,7 @@ "column": 23 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/function/export-default/output.json b/packages/babel-parser/test/fixtures/typescript/function/export-default/output.json index 9ed0b4a6e22b..42c8c034dd19 100644 --- a/packages/babel-parser/test/fixtures/typescript/function/export-default/output.json +++ b/packages/babel-parser/test/fixtures/typescript/function/export-default/output.json @@ -43,6 +43,7 @@ "column": 42 } }, + "exportKind": "value", "declaration": { "type": "TSDeclareFunction", "start": 15, diff --git a/packages/babel-parser/test/fixtures/typescript/function/overloads/output.json b/packages/babel-parser/test/fixtures/typescript/function/overloads/output.json index 2f66c7db6e15..0ed87c620a55 100644 --- a/packages/babel-parser/test/fixtures/typescript/function/overloads/output.json +++ b/packages/babel-parser/test/fixtures/typescript/function/overloads/output.json @@ -43,6 +43,7 @@ "column": 37 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -173,6 +174,7 @@ "column": 37 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/import/export-named-import-require/output.json b/packages/babel-parser/test/fixtures/typescript/import/export-named-import-require/output.json index 4c31f00de348..e69632d570ab 100644 --- a/packages/babel-parser/test/fixtures/typescript/import/export-named-import-require/output.json +++ b/packages/babel-parser/test/fixtures/typescript/import/export-named-import-require/output.json @@ -111,6 +111,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/import/not-top-level/output.json b/packages/babel-parser/test/fixtures/typescript/import/not-top-level/output.json index d8c247aa8f57..1a7dcef7a96a 100644 --- a/packages/babel-parser/test/fixtures/typescript/import/not-top-level/output.json +++ b/packages/babel-parser/test/fixtures/typescript/import/not-top-level/output.json @@ -92,6 +92,7 @@ "column": 27 } }, + "importKind": "value", "specifiers": [ { "type": "ImportNamespaceSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/interface/export/output.json b/packages/babel-parser/test/fixtures/typescript/interface/export/output.json index 1ad5c8ab4df6..f7fe8f0c03eb 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/export/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/export/output.json @@ -43,6 +43,7 @@ "column": 21 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -108,6 +109,7 @@ "column": 29 } }, + "exportKind": "value", "declaration": { "type": "TSInterfaceDeclaration", "start": 37, diff --git a/packages/babel-parser/test/fixtures/typescript/module-namespace/head-export/output.json b/packages/babel-parser/test/fixtures/typescript/module-namespace/head-export/output.json index 178571a6d6df..d731128cf4b1 100644 --- a/packages/babel-parser/test/fixtures/typescript/module-namespace/head-export/output.json +++ b/packages/babel-parser/test/fixtures/typescript/module-namespace/head-export/output.json @@ -43,6 +43,7 @@ "column": 23 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -140,6 +141,7 @@ "column": 18 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/regression/is-default-export/output.json b/packages/babel-parser/test/fixtures/typescript/regression/is-default-export/output.json index 406eee594b58..c2d937d1bd58 100644 --- a/packages/babel-parser/test/fixtures/typescript/regression/is-default-export/output.json +++ b/packages/babel-parser/test/fixtures/typescript/regression/is-default-export/output.json @@ -43,6 +43,7 @@ "column": 23 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { @@ -107,6 +108,7 @@ "column": 16 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { @@ -157,6 +159,7 @@ "column": 21 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-after/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-after/output.json index c207baa1677a..3532a53a3ffd 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-after/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-after/output.json @@ -109,6 +109,7 @@ "column": 15 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-before/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-before/output.json index b7071b10e90f..df5b73f76cf8 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-before/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-declare-function-before/output.json @@ -43,6 +43,7 @@ "column": 15 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-enum-after/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-enum-after/output.json index c8738ce00309..4033028297ce 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-enum-after/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-enum-after/output.json @@ -94,6 +94,7 @@ "column": 26 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-enum-before/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-enum-before/output.json index 43ce8b85cb55..40da2edef6d4 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-enum-before/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-enum-before/output.json @@ -43,6 +43,7 @@ "column": 26 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-interface-after/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-interface-after/output.json index 9e575d18d39e..263dec8e48ce 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-interface-after/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-interface-after/output.json @@ -91,6 +91,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-interface-before/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-interface-before/output.json index dd48538d82d9..b568f8c09849 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-interface-before/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-interface-before/output.json @@ -43,6 +43,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-namespace/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-namespace/output.json index ec2b4c8349b5..301c98de69f7 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-namespace/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-namespace/output.json @@ -91,6 +91,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-type-after/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-type-after/output.json index d4259d15a749..3053978d881c 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-type-after/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-type-after/output.json @@ -90,6 +90,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/export-type-before/output.json b/packages/babel-parser/test/fixtures/typescript/scope/export-type-before/output.json index 5086f1f05376..7b700a883bdb 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/export-type-before/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/export-type-before/output.json @@ -43,6 +43,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/function-type-before-declaration/output.json b/packages/babel-parser/test/fixtures/typescript/scope/function-type-before-declaration/output.json index c17c84eca906..d3685c7d0db1 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/function-type-before-declaration/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/function-type-before-declaration/output.json @@ -160,6 +160,7 @@ "column": 13 } }, + "exportKind": "value", "specifiers": [ { "type": "ExportSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var-2/output.json b/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var-2/output.json index 9bb0caf6808d..e1b72e08c71d 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var-2/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var-2/output.json @@ -43,6 +43,7 @@ "column": 1 } }, + "declare": true, "id": { "type": "Identifier", "start": 14, @@ -76,8 +77,7 @@ } }, "body": [] - }, - "declare": true + } }, { "type": "TSModuleDeclaration", @@ -139,6 +139,7 @@ "column": 22 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var/output.json b/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var/output.json index 77f4b16a6ac7..0de95961df1a 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/module-declaration-var/output.json @@ -43,6 +43,7 @@ "column": 1 } }, + "declare": true, "id": { "type": "Identifier", "start": 14, @@ -76,8 +77,7 @@ } }, "body": [] - }, - "declare": true + } }, { "type": "TSModuleDeclaration", @@ -142,6 +142,7 @@ "column": 22 } }, + "exportKind": "value", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/scope/redeclaration-import-ambient-class/output.json b/packages/babel-parser/test/fixtures/typescript/scope/redeclaration-import-ambient-class/output.json index fe9e84eee59d..351802cc6230 100644 --- a/packages/babel-parser/test/fixtures/typescript/scope/redeclaration-import-ambient-class/output.json +++ b/packages/babel-parser/test/fixtures/typescript/scope/redeclaration-import-ambient-class/output.json @@ -43,6 +43,7 @@ "column": 38 } }, + "importKind": "value", "specifiers": [ { "type": "ImportDefaultSpecifier", diff --git a/packages/babel-parser/test/fixtures/typescript/type-alias/export/output.json b/packages/babel-parser/test/fixtures/typescript/type-alias/export/output.json index 829dc8b3afcc..7f9c1f9fd3b7 100644 --- a/packages/babel-parser/test/fixtures/typescript/type-alias/export/output.json +++ b/packages/babel-parser/test/fixtures/typescript/type-alias/export/output.json @@ -43,6 +43,7 @@ "column": 23 } }, + "exportKind": "type", "specifiers": [], "source": null, "declaration": { diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/input.ts b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/input.ts new file mode 100644 index 000000000000..bcfb7c11d873 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/input.ts @@ -0,0 +1 @@ +import type FooDefault, { Bar, Baz } from "module"; \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/output.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/output.json new file mode 100644 index 000000000000..13de762ac455 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration-error/output.json @@ -0,0 +1,206 @@ +{ + "type": "File", + "start": 0, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "errors": [ + "SyntaxError: A type-only import can specify a default import or named bindings, but not both. (1:0)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start": 0, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "importKind": "type", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "start": 12, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "local": { + "type": "Identifier", + "start": 12, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 22 + }, + "identifierName": "FooDefault" + }, + "name": "FooDefault" + } + }, + { + "type": "ImportSpecifier", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "imported": { + "type": "Identifier", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "Bar" + }, + "name": "Bar" + }, + "local": { + "type": "Identifier", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "Bar" + }, + "name": "Bar" + } + }, + { + "type": "ImportSpecifier", + "start": 31, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "imported": { + "type": "Identifier", + "start": 31, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 34 + }, + "identifierName": "Baz" + }, + "name": "Baz" + }, + "local": { + "type": "Identifier", + "start": 31, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 34 + }, + "identifierName": "Baz" + }, + "name": "Baz" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 42, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 50 + } + }, + "extra": { + "rawValue": "module", + "raw": "\"module\"" + }, + "value": "module" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/input.ts b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/input.ts new file mode 100644 index 000000000000..2fcb758ba25f --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/input.ts @@ -0,0 +1,3 @@ +import type T from './mod'; +import type { A, B } from './mod'; +import type * as Types from './mod'; diff --git a/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/output.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/output.json new file mode 100644 index 000000000000..bd2d69938b98 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/import-type-declaration/output.json @@ -0,0 +1,311 @@ +{ + "type": "File", + "start": 0, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "importKind": "type", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "local": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + }, + "identifierName": "T" + }, + "name": "T" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 19, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "extra": { + "rawValue": "./mod", + "raw": "'./mod'" + }, + "value": "./mod" + } + }, + { + "type": "ImportDeclaration", + "start": 28, + "end": 62, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 34 + } + }, + "importKind": "type", + "specifiers": [ + { + "type": "ImportSpecifier", + "start": 42, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "imported": { + "type": "Identifier", + "start": 42, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + }, + "identifierName": "A" + }, + "name": "A" + }, + "local": { + "type": "Identifier", + "start": 42, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + }, + "identifierName": "A" + }, + "name": "A" + } + }, + { + "type": "ImportSpecifier", + "start": 45, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 18 + } + }, + "imported": { + "type": "Identifier", + "start": 45, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 18 + }, + "identifierName": "B" + }, + "name": "B" + }, + "local": { + "type": "Identifier", + "start": 45, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 18 + }, + "identifierName": "B" + }, + "name": "B" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 54, + "end": 61, + "loc": { + "start": { + "line": 2, + "column": 26 + }, + "end": { + "line": 2, + "column": 33 + } + }, + "extra": { + "rawValue": "./mod", + "raw": "'./mod'" + }, + "value": "./mod" + } + }, + { + "type": "ImportDeclaration", + "start": 63, + "end": 99, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "importKind": "type", + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "start": 75, + "end": 85, + "loc": { + "start": { + "line": 3, + "column": 12 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "local": { + "type": "Identifier", + "start": 80, + "end": 85, + "loc": { + "start": { + "line": 3, + "column": 17 + }, + "end": { + "line": 3, + "column": 22 + }, + "identifierName": "Types" + }, + "name": "Types" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 91, + "end": 98, + "loc": { + "start": { + "line": 3, + "column": 28 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "extra": { + "rawValue": "./mod", + "raw": "'./mod'" + }, + "value": "./mod" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/import/input.ts b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic/input.ts similarity index 100% rename from packages/babel-parser/test/fixtures/typescript/types/import/input.ts rename to packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic/input.ts diff --git a/packages/babel-parser/test/fixtures/typescript/types/import/output.json b/packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic/output.json similarity index 100% rename from packages/babel-parser/test/fixtures/typescript/types/import/output.json rename to packages/babel-parser/test/fixtures/typescript/types/import-type-dynamic/output.json diff --git a/packages/babel-plugin-transform-typescript/src/index.js b/packages/babel-plugin-transform-typescript/src/index.js index 906800fec056..f2d37c5a13c3 100644 --- a/packages/babel-plugin-transform-typescript/src/index.js +++ b/packages/babel-plugin-transform-typescript/src/index.js @@ -50,6 +50,7 @@ export default declare( jsxPragma = "React", allowNamespaces = false, allowDeclareFields = false, + onlyRemoveTypeImports = false, }, ) => { api.assertVersion(7); @@ -166,43 +167,52 @@ export default declare( // remove type imports for (let stmt of path.get("body")) { if (t.isImportDeclaration(stmt)) { - // Note: this will allow both `import { } from "m"` and `import "m";`. - // In TypeScript, the former would be elided. - if (stmt.node.specifiers.length === 0) { + if (stmt.node.importKind === "type") { + stmt.remove(); continue; } - let allElided = true; - const importsToRemove: Path[] = []; - - for (const specifier of stmt.node.specifiers) { - const binding = stmt.scope.getBinding(specifier.local.name); - - // The binding may not exist if the import node was explicitly - // injected by another plugin. Currently core does not do a good job - // of keeping scope bindings synchronized with the AST. For now we - // just bail if there is no binding, since chances are good that if - // the import statement was injected then it wasn't a typescript type - // import anyway. - if ( - binding && - isImportTypeOnly({ - binding, - programPath: path, - jsxPragma: fileJsxPragma || jsxPragma, - }) - ) { - importsToRemove.push(binding.path); - } else { - allElided = false; + // If onlyRemoveTypeImports is `true`, only remove type-only imports + // and exports introduced in TypeScript 3.8. + if (!onlyRemoveTypeImports) { + // Note: this will allow both `import { } from "m"` and `import "m";`. + // In TypeScript, the former would be elided. + if (stmt.node.specifiers.length === 0) { + continue; } - } - if (allElided) { - stmt.remove(); - } else { - for (const importPath of importsToRemove) { - importPath.remove(); + let allElided = true; + const importsToRemove: Path[] = []; + + for (const specifier of stmt.node.specifiers) { + const binding = stmt.scope.getBinding(specifier.local.name); + + // The binding may not exist if the import node was explicitly + // injected by another plugin. Currently core does not do a good job + // of keeping scope bindings synchronized with the AST. For now we + // just bail if there is no binding, since chances are good that if + // the import statement was injected then it wasn't a typescript type + // import anyway. + if ( + binding && + isImportTypeOnly({ + binding, + programPath: path, + jsxPragma: fileJsxPragma || jsxPragma, + }) + ) { + importsToRemove.push(binding.path); + } else { + allElided = false; + } + } + + if (allElided) { + stmt.remove(); + } else { + for (const importPath of importsToRemove) { + importPath.remove(); + } } } @@ -232,7 +242,18 @@ export default declare( }, ExportNamedDeclaration(path) { + if (path.node.exportKind === "type") { + path.remove(); + return; + } + // remove export declaration if it's exporting only types + // This logic is needed when exportKind is "value", because + // currently the "type" keyword is optional. + // TODO: + // Also, currently @babel/parser sets exportKind to "value" for + // export interface A {} + // etc. if ( !path.node.source && path.node.specifiers.length > 0 && diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/input.ts new file mode 100644 index 000000000000..d49327a766e3 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/input.ts @@ -0,0 +1,2 @@ +export type { A } from "./mod"; +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/output.mjs new file mode 100644 index 000000000000..092bc2b04126 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type-from/output.mjs @@ -0,0 +1 @@ +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/input.ts new file mode 100644 index 000000000000..4a7f4367fecb --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/input.ts @@ -0,0 +1,4 @@ +type A = 2; + +export type { A }; +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/output.mjs new file mode 100644 index 000000000000..092bc2b04126 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export-type/output.mjs @@ -0,0 +1 @@ +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/input.ts new file mode 100644 index 000000000000..744ae808eaa9 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/input.ts @@ -0,0 +1,13 @@ +import a from "a"; +import { b } from "b"; +import { c as c2 } from "c"; +import d, { d2 } from "d"; +import e, { e3 as e4 } from "e"; + +import {} from "f"; +import "g"; + +import type H from "h"; +import type { I, I2 } from "i"; +import type * as J from "j"; +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/output.mjs new file mode 100644 index 000000000000..25cfa2dc5c2b --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-removed-exceptions/output.mjs @@ -0,0 +1,3 @@ +import "f"; +import "g"; +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/input.ts new file mode 100644 index 000000000000..80988c65072d --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/input.ts @@ -0,0 +1,4 @@ +import type A from "x"; +// TODO: This should not be removed +import B from "y"; +; \ No newline at end of file diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/output.mjs new file mode 100644 index 000000000000..3e83039477c8 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type-not-removed/output.mjs @@ -0,0 +1,2 @@ +// TODO: This should not be removed +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/input.ts new file mode 100644 index 000000000000..50348ae13866 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/input.ts @@ -0,0 +1,4 @@ +import type T from './mod'; +import type { A, B } from './mod'; +import type * as Types from './mod'; +; \ No newline at end of file diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/output.mjs new file mode 100644 index 000000000000..092bc2b04126 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import-type/output.mjs @@ -0,0 +1 @@ +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/input.ts new file mode 100644 index 000000000000..744ae808eaa9 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/input.ts @@ -0,0 +1,13 @@ +import a from "a"; +import { b } from "b"; +import { c as c2 } from "c"; +import d, { d2 } from "d"; +import e, { e3 as e4 } from "e"; + +import {} from "f"; +import "g"; + +import type H from "h"; +import type { I, I2 } from "i"; +import type * as J from "j"; +; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/options.json new file mode 100644 index 000000000000..ce280969f6e9 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [[ + "transform-typescript", + { + "onlyRemoveTypeImports": true + } + ]] +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/output.mjs new file mode 100644 index 000000000000..d86475cacac8 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/only-remove-type-imports/output.mjs @@ -0,0 +1,8 @@ +import a from "a"; +import { b } from "b"; +import { c as c2 } from "c"; +import d, { d2 } from "d"; +import e, { e3 as e4 } from "e"; +import "f"; +import "g"; +; diff --git a/packages/babel-preset-typescript/src/index.js b/packages/babel-preset-typescript/src/index.js index f3159543f66d..74f885371395 100644 --- a/packages/babel-preset-typescript/src/index.js +++ b/packages/babel-preset-typescript/src/index.js @@ -5,11 +5,12 @@ export default declare( ( api, { - jsxPragma, allExtensions = false, - isTSX = false, - allowNamespaces, allowDeclareFields, + allowNamespaces, + jsxPragma, + isTSX = false, + onlyRemoveTypeImports, }, ) => { api.assertVersion(7); @@ -27,10 +28,11 @@ export default declare( } const pluginOptions = isTSX => ({ - jsxPragma, - isTSX, - allowNamespaces, allowDeclareFields, + allowNamespaces, + isTSX, + jsxPragma, + onlyRemoveTypeImports, }); return { diff --git a/packages/babel-types/src/definitions/es2015.js b/packages/babel-types/src/definitions/es2015.js index 853af1b12e65..d6a5dcb8ef36 100644 --- a/packages/babel-types/src/definitions/es2015.js +++ b/packages/babel-types/src/definitions/es2015.js @@ -382,7 +382,8 @@ defineType("ImportDeclaration", { validate: assertNodeType("StringLiteral"), }, importKind: { - // Handle Flowtype's extension "import {typeof foo} from" + // Handle TypeScript/Flowtype's extension "import type foo from" + // TypeScript doesn't support typeof validate: assertOneOf("type", "typeof", "value"), optional: true, },