diff --git a/packages/babel-generator/src/generators/typescript.js b/packages/babel-generator/src/generators/typescript.js index 4ff2fe1ad188..aa5e4ce4cde6 100644 --- a/packages/babel-generator/src/generators/typescript.js +++ b/packages/babel-generator/src/generators/typescript.js @@ -197,11 +197,17 @@ export function TSTypeReference(node) { } export function TSTypePredicate(node) { + if (node.assertsModifier) { + this.word("asserts"); + this.space(); + } this.print(node.parameterName); - this.space(); - this.word("is"); - this.space(); - this.print(node.typeAnnotation.typeAnnotation); + if (node.typeAnnotation) { + this.space(); + this.word("is"); + this.space(); + this.print(node.typeAnnotation.typeAnnotation); + } } export function TSTypeQuery(node) { diff --git a/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/input.js b/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/input.js new file mode 100644 index 000000000000..67e467cda8ed --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/input.js @@ -0,0 +1,2 @@ +(x: any): asserts x => true; +(x: any): asserts x is boolean => true; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/output.js b/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/output.js new file mode 100644 index 000000000000..b0befa69dc24 --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/arrow-function-assertion/output.js @@ -0,0 +1,3 @@ +(x: any): asserts x => true; + +(x: any): asserts x is boolean => true; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/typescript/function-assertion/input.js b/packages/babel-generator/test/fixtures/typescript/function-assertion/input.js new file mode 100644 index 000000000000..17db65c5a77f --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/function-assertion/input.js @@ -0,0 +1,2 @@ +function f(x: any): asserts x {} +(function(x: any): asserts x is boolean {}) diff --git a/packages/babel-generator/test/fixtures/typescript/function-assertion/output.js b/packages/babel-generator/test/fixtures/typescript/function-assertion/output.js new file mode 100644 index 000000000000..b55c84620cc9 --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/function-assertion/output.js @@ -0,0 +1,3 @@ +function f(x: any): asserts x {} + +(function (x: any): asserts x is boolean {}); \ 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 187dd540520a..a47dfac29ba6 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -904,21 +904,34 @@ export default (superClass: Class): Class => const t: N.TsTypeAnnotation = this.startNode(); this.expect(returnToken); + const assertsModifier = this.tsTryParse( + this.tsParseTypePredicateAssertsModifier.bind(this), + ); + const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this)); if (!typePredicateVariable) { - return this.tsParseTypeAnnotation(/* eatColon */ false, t); + if (!assertsModifier) { + // : type + return this.tsParseTypeAnnotation(/* eatColon */ false, t); + } + + // : asserts foo + const node = this.startNodeAtNode(t); + node.parameterName = this.parseIdentifier(); + node.assertsModifier = assertsModifier; + t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); + return this.finishNode(t, "TSTypeAnnotation"); } + // : foo is type const type = this.tsParseTypeAnnotation(/* eatColon */ false); - - const node: N.TsTypePredicate = this.startNodeAtNode( - typePredicateVariable, - ); + const node = this.startNodeAtNode(t); node.parameterName = typePredicateVariable; node.typeAnnotation = type; + node.assertsModifier = assertsModifier; t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); return this.finishNode(t, "TSTypeAnnotation"); }); @@ -946,6 +959,23 @@ export default (superClass: Class): Class => } } + tsParseTypePredicateAssertsModifier(): boolean { + if (!this.tsIsIdentifier()) { + return false; + } + + const id = this.parseIdentifier(); + if ( + id.name !== "asserts" || + this.hasPrecedingLineBreak() || + !this.tsIsIdentifier() + ) { + return false; + } + + return true; + } + tsParseTypeAnnotation( eatColon = true, t: N.TsTypeAnnotation = this.startNode(), diff --git a/packages/babel-parser/test/fixtures/typescript/arrow-function/predicate-types/output.json b/packages/babel-parser/test/fixtures/typescript/arrow-function/predicate-types/output.json index e1f9142855b1..45239b7a0c11 100644 --- a/packages/babel-parser/test/fixtures/typescript/arrow-function/predicate-types/output.json +++ b/packages/babel-parser/test/fixtures/typescript/arrow-function/predicate-types/output.json @@ -73,12 +73,12 @@ }, "typeAnnotation": { "type": "TSTypePredicate", - "start": 10, + "start": 8, "end": 21, "loc": { "start": { "line": 1, - "column": 10 + "column": 8 }, "end": { "line": 1, diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/input.ts b/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/input.ts new file mode 100644 index 000000000000..5989d8d4f2b4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/input.ts @@ -0,0 +1,3 @@ +const assert1 = (value: unknown): asserts value is string => {} +const assert2 = (value: unknown): asserts value => {} +const assert3 = (value: unknown): asserts => {} diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/output.json b/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/output.json new file mode 100644 index 000000000000..e368637de0a9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/arrow-function/output.json @@ -0,0 +1,610 @@ +{ + "type": "File", + "start": 0, + "end": 165, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 165, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 13 + }, + "identifierName": "assert1" + }, + "name": "assert1" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 16, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "returnType": { + "type": "TSTypeAnnotation", + "start": 32, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 32, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "parameterName": { + "type": "Identifier", + "start": 42, + "end": 47, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 47 + }, + "identifierName": "value" + }, + "name": "value" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 51, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "start": 51, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 57 + } + } + } + }, + "assertsModifier": true + } + }, + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 17, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 31 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 22, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 24, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 31 + } + } + } + } + } + ], + "body": { + "type": "BlockStatement", + "start": 61, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 61 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "body": [], + "directives": [] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 64, + "end": 117, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 53 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 70, + "end": 117, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 53 + } + }, + "id": { + "type": "Identifier", + "start": 70, + "end": 77, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "assert2" + }, + "name": "assert2" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 80, + "end": 117, + "loc": { + "start": { + "line": 2, + "column": 16 + }, + "end": { + "line": 2, + "column": 53 + } + }, + "returnType": { + "type": "TSTypeAnnotation", + "start": 96, + "end": 111, + "loc": { + "start": { + "line": 2, + "column": 32 + }, + "end": { + "line": 2, + "column": 47 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 96, + "end": 111, + "loc": { + "start": { + "line": 2, + "column": 32 + }, + "end": { + "line": 2, + "column": 47 + } + }, + "parameterName": { + "type": "Identifier", + "start": 106, + "end": 111, + "loc": { + "start": { + "line": 2, + "column": 42 + }, + "end": { + "line": 2, + "column": 47 + }, + "identifierName": "value" + }, + "name": "value" + }, + "assertsModifier": true + } + }, + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 81, + "end": 95, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 31 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 86, + "end": 95, + "loc": { + "start": { + "line": 2, + "column": 22 + }, + "end": { + "line": 2, + "column": 31 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 88, + "end": 95, + "loc": { + "start": { + "line": 2, + "column": 24 + }, + "end": { + "line": 2, + "column": 31 + } + } + } + } + } + ], + "body": { + "type": "BlockStatement", + "start": 115, + "end": 117, + "loc": { + "start": { + "line": 2, + "column": 51 + }, + "end": { + "line": 2, + "column": 53 + } + }, + "body": [], + "directives": [] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 118, + "end": 165, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 124, + "end": 165, + "loc": { + "start": { + "line": 3, + "column": 6 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "id": { + "type": "Identifier", + "start": 124, + "end": 131, + "loc": { + "start": { + "line": 3, + "column": 6 + }, + "end": { + "line": 3, + "column": 13 + }, + "identifierName": "assert3" + }, + "name": "assert3" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 134, + "end": 165, + "loc": { + "start": { + "line": 3, + "column": 16 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "returnType": { + "type": "TSTypeAnnotation", + "start": 150, + "end": 159, + "loc": { + "start": { + "line": 3, + "column": 32 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 152, + "end": 159, + "loc": { + "start": { + "line": 3, + "column": 34 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "typeName": { + "type": "Identifier", + "start": 152, + "end": 159, + "loc": { + "start": { + "line": 3, + "column": 34 + }, + "end": { + "line": 3, + "column": 41 + }, + "identifierName": "asserts" + }, + "name": "asserts" + } + } + }, + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 135, + "end": 149, + "loc": { + "start": { + "line": 3, + "column": 17 + }, + "end": { + "line": 3, + "column": 31 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 140, + "end": 149, + "loc": { + "start": { + "line": 3, + "column": 22 + }, + "end": { + "line": 3, + "column": 31 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 142, + "end": 149, + "loc": { + "start": { + "line": 3, + "column": 24 + }, + "end": { + "line": 3, + "column": 31 + } + } + } + } + } + ], + "body": { + "type": "BlockStatement", + "start": 163, + "end": 165, + "loc": { + "start": { + "line": 3, + "column": 45 + }, + "end": { + "line": 3, + "column": 47 + } + }, + "body": [], + "directives": [] + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/input.ts b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/input.ts new file mode 100644 index 000000000000..d5ee9a42ce01 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/input.ts @@ -0,0 +1 @@ +declare function assertIsString(value: unknown): asserts; diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/output.json b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/output.json new file mode 100644 index 000000000000..dc6f8702bdce --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-as-identifier/output.json @@ -0,0 +1,166 @@ +{ + "type": "File", + "start": 0, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSDeclareFunction", + "start": 0, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 31 + }, + "identifierName": "assertIsString" + }, + "name": "assertIsString" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 32, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 37, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 46 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 39, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 46 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 47, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 49, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "typeName": { + "type": "Identifier", + "start": 49, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 56 + }, + "identifierName": "asserts" + }, + "name": "asserts" + } + } + }, + "declare": true + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/input.ts b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/input.ts new file mode 100644 index 000000000000..63613906e9fd --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/input.ts @@ -0,0 +1 @@ +declare function assertIsString(value: unknown): asserts value; diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/output.json b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/output.json new file mode 100644 index 000000000000..a7b32e23d170 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-var/output.json @@ -0,0 +1,167 @@ +{ + "type": "File", + "start": 0, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSDeclareFunction", + "start": 0, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 31 + }, + "identifierName": "assertIsString" + }, + "name": "assertIsString" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 32, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 37, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 46 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 39, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 46 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 47, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 47, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "parameterName": { + "type": "Identifier", + "start": 57, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 57 + }, + "end": { + "line": 1, + "column": 62 + }, + "identifierName": "value" + }, + "name": "value" + }, + "assertsModifier": true + } + }, + "declare": true + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/input.ts b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/input.ts new file mode 100644 index 000000000000..9456a5cb2e50 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/input.ts @@ -0,0 +1 @@ +declare function assertIsString(value: unknown): asserts value is string; diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/output.json b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/output.json new file mode 100644 index 000000000000..ca83a725e2d5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/asserts-with-predicate/output.json @@ -0,0 +1,197 @@ +{ + "type": "File", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSDeclareFunction", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 31 + }, + "identifierName": "assertIsString" + }, + "name": "assertIsString" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 32, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 37, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 46 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 39, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 46 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 47, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 72 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 47, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 72 + } + }, + "parameterName": { + "type": "Identifier", + "start": 57, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 57 + }, + "end": { + "line": 1, + "column": 62 + }, + "identifierName": "value" + }, + "name": "value" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 66, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 72 + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "start": 66, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 72 + } + } + } + }, + "assertsModifier": true + } + }, + "declare": true + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/input.ts b/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/input.ts new file mode 100644 index 000000000000..b04da8349ca2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/input.ts @@ -0,0 +1,3 @@ +function asserts1 (value: unknown): asserts value is string {} +function asserts2 (value: unknown): asserts value {} +function asserts3 (value: unknown): asserts {} diff --git a/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/output.json b/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/output.json new file mode 100644 index 000000000000..96aea85b2926 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/assert-predicate/function-declaration/output.json @@ -0,0 +1,508 @@ +{ + "type": "File", + "start": 0, + "end": 163, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 46 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 163, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 46 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "id": { + "type": "Identifier", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "asserts1" + }, + "name": "asserts1" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 19, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 33 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 24, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 26, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 33 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 34, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 34 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 34, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 34 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "parameterName": { + "type": "Identifier", + "start": 44, + "end": 49, + "loc": { + "start": { + "line": 1, + "column": 44 + }, + "end": { + "line": 1, + "column": 49 + }, + "identifierName": "value" + }, + "name": "value" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 53, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 53 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "start": 53, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 53 + }, + "end": { + "line": 1, + "column": 59 + } + } + } + }, + "assertsModifier": true + } + }, + "body": { + "type": "BlockStatement", + "start": 60, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 60 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "body": [], + "directives": [] + } + }, + { + "type": "FunctionDeclaration", + "start": 64, + "end": 116, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 52 + } + }, + "id": { + "type": "Identifier", + "start": 73, + "end": 81, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 17 + }, + "identifierName": "asserts2" + }, + "name": "asserts2" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 83, + "end": 97, + "loc": { + "start": { + "line": 2, + "column": 19 + }, + "end": { + "line": 2, + "column": 33 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 88, + "end": 97, + "loc": { + "start": { + "line": 2, + "column": 24 + }, + "end": { + "line": 2, + "column": 33 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 90, + "end": 97, + "loc": { + "start": { + "line": 2, + "column": 26 + }, + "end": { + "line": 2, + "column": 33 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 98, + "end": 113, + "loc": { + "start": { + "line": 2, + "column": 34 + }, + "end": { + "line": 2, + "column": 49 + } + }, + "typeAnnotation": { + "type": "TSTypePredicate", + "start": 98, + "end": 113, + "loc": { + "start": { + "line": 2, + "column": 34 + }, + "end": { + "line": 2, + "column": 49 + } + }, + "parameterName": { + "type": "Identifier", + "start": 108, + "end": 113, + "loc": { + "start": { + "line": 2, + "column": 44 + }, + "end": { + "line": 2, + "column": 49 + }, + "identifierName": "value" + }, + "name": "value" + }, + "assertsModifier": true + } + }, + "body": { + "type": "BlockStatement", + "start": 114, + "end": 116, + "loc": { + "start": { + "line": 2, + "column": 50 + }, + "end": { + "line": 2, + "column": 52 + } + }, + "body": [], + "directives": [] + } + }, + { + "type": "FunctionDeclaration", + "start": 117, + "end": 163, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 46 + } + }, + "id": { + "type": "Identifier", + "start": 126, + "end": 134, + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 3, + "column": 17 + }, + "identifierName": "asserts3" + }, + "name": "asserts3" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 136, + "end": 150, + "loc": { + "start": { + "line": 3, + "column": 19 + }, + "end": { + "line": 3, + "column": 33 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 141, + "end": 150, + "loc": { + "start": { + "line": 3, + "column": 24 + }, + "end": { + "line": 3, + "column": 33 + } + }, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start": 143, + "end": 150, + "loc": { + "start": { + "line": 3, + "column": 26 + }, + "end": { + "line": 3, + "column": 33 + } + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start": 151, + "end": 160, + "loc": { + "start": { + "line": 3, + "column": 34 + }, + "end": { + "line": 3, + "column": 43 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 153, + "end": 160, + "loc": { + "start": { + "line": 3, + "column": 36 + }, + "end": { + "line": 3, + "column": 43 + } + }, + "typeName": { + "type": "Identifier", + "start": 153, + "end": 160, + "loc": { + "start": { + "line": 3, + "column": 36 + }, + "end": { + "line": 3, + "column": 43 + }, + "identifierName": "asserts" + }, + "name": "asserts" + } + } + }, + "body": { + "type": "BlockStatement", + "start": 161, + "end": 163, + "loc": { + "start": { + "line": 3, + "column": 44 + }, + "end": { + "line": 3, + "column": 46 + } + }, + "body": [], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/function/predicate-types/output.json b/packages/babel-parser/test/fixtures/typescript/function/predicate-types/output.json index 85ab4987f1c2..90bae5b4ceda 100644 --- a/packages/babel-parser/test/fixtures/typescript/function/predicate-types/output.json +++ b/packages/babel-parser/test/fixtures/typescript/function/predicate-types/output.json @@ -127,12 +127,12 @@ }, "typeAnnotation": { "type": "TSTypePredicate", - "start": 20, + "start": 18, "end": 32, "loc": { "start": { "line": 1, - "column": 20 + "column": 18 }, "end": { "line": 1, @@ -302,12 +302,12 @@ }, "typeAnnotation": { "type": "TSTypePredicate", - "start": 55, + "start": 53, "end": 67, "loc": { "start": { "line": 2, - "column": 19 + "column": 17 }, "end": { "line": 2, diff --git a/packages/babel-types/src/definitions/typescript.js b/packages/babel-types/src/definitions/typescript.js index af34dbfc6255..b20448af8d1e 100644 --- a/packages/babel-types/src/definitions/typescript.js +++ b/packages/babel-types/src/definitions/typescript.js @@ -175,10 +175,11 @@ defineType("TSTypeReference", { defineType("TSTypePredicate", { aliases: ["TSType"], - visitor: ["parameterName", "typeAnnotation"], + visitor: ["parameterName", "typeAnnotation", "assertsModifier"], fields: { parameterName: validateType(["Identifier", "TSThisType"]), - typeAnnotation: validateType("TSTypeAnnotation"), + typeAnnotation: validateOptionalType("TSTypeAnnotation"), + assertsModifier: validate(bool), }, });