diff --git a/packages/babel-parser/src/plugins/typescript.js b/packages/babel-parser/src/plugins/typescript.js index e53749a9e5..0940878ae2 100644 --- a/packages/babel-parser/src/plugins/typescript.js +++ b/packages/babel-parser/src/plugins/typescript.js @@ -660,6 +660,19 @@ export default (superClass: Class): Class => return this.finishNode(node, "TSLiteralType"); } + tsParseTemplateLiteralType(): N.TsType { + const node: N.TsLiteralType = this.startNode(); + const templateNode = this.parseTemplate(false); + if (templateNode.expressions.length > 0) { + throw this.raise( + templateNode.expressions[0].start, + "Template literal types cannot have any substitution", + ); + } + node.literal = templateNode; + return this.finishNode(node, "TSLiteralType"); + } + tsParseNonArrayType(): N.TsType { switch (this.state.type) { case tt.name: @@ -712,6 +725,8 @@ export default (superClass: Class): Class => return this.tsParseTupleType(); case tt.parenL: return this.tsParseParenthesizedType(); + case tt.backQuote: + return this.tsParseTemplateLiteralType(); } throw this.unexpected(); diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.js index 5c49be4472..22ceb9e2df 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.js @@ -1308,7 +1308,7 @@ export type TsMappedType = TsTypeBase & { export type TsLiteralType = TsTypeBase & { type: "TSLiteralType", - literal: NumericLiteral | StringLiteral | BooleanLiteral, + literal: NumericLiteral | StringLiteral | BooleanLiteral | TemplateLiteral, }; export type TsImportType = TsTypeBase & { diff --git a/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/input.js b/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/input.js new file mode 100644 index 0000000000..089ff63ba1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/input.js @@ -0,0 +1 @@ +let x: `foo`; diff --git a/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/output.json b/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/output.json new file mode 100644 index 0000000000..a153fb364a --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/literal-string-1/output.json @@ -0,0 +1,154 @@ +{ + "type": "File", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "id": { + "type": "Identifier", + "start": 4, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "x" + }, + "name": "x", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 5, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "typeAnnotation": { + "type": "TSLiteralType", + "start": 7, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "literal": { + "type": "TemplateLiteral", + "start": 7, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "expressions": [], + "quasis": [ + { + "type": "TemplateElement", + "start": 8, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "value": { + "raw": "foo", + "cooked": "foo" + }, + "tail": true + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "let" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/input.js b/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/input.js new file mode 100644 index 0000000000..e21e6a4d4b --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/input.js @@ -0,0 +1 @@ +let x: `foo-${bar}`; diff --git a/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/options.json b/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/options.json new file mode 100644 index 0000000000..3c001f6afd --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/literal-string-2/options.json @@ -0,0 +1,7 @@ +{ + "sourceType": "module", + "plugins": [ + "typescript" + ], + "throws": "Template literal types cannot have any substitution (1:14)" +} \ No newline at end of file