diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index b85c41371a68..47782c7b8273 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -1816,25 +1816,27 @@ export default (superClass: Class): Class => } } - parseExprListItem( - allowEmpty: ?boolean, - refExpressionErrors?: ?ExpressionErrors, - refNeedsArrowPos: ?Pos, - allowPlaceholder: ?boolean, - ): ?N.Expression { - const node = super.parseExprListItem( - allowEmpty, - refExpressionErrors, - refNeedsArrowPos, - allowPlaceholder, - ); - - // Handle `func(a: T)` or `func(a: T)` - if (!refNeedsArrowPos && node?.type === "TSTypeCastExpression") { - this.raise(node.start, TSErrors.UnexpectedTypeAnnotation); - } + tsCheckForInvalidTypeCasts(items: $ReadOnlyArray) { + items.forEach(node => { + if (node?.type === "TSTypeCastExpression") { + this.raise( + node.typeAnnotation.start, + TSErrors.UnexpectedTypeAnnotation, + ); + } + }); + } - return node; + toReferencedList( + exprList: $ReadOnlyArray, + isInParens?: boolean, // eslint-disable-line no-unused-vars + ): $ReadOnlyArray { + // Handles invalid scenarios like: `f(a:b)`, `(a:b);`, and `(a:b,c:d)`. + // + // Note that `f(a:b)` goes through a different path and is handled + // in `parseSubscript` directly. + this.tsCheckForInvalidTypeCasts(exprList); + return exprList; } parseSubscript( @@ -1886,6 +1888,10 @@ export default (superClass: Class): Class => tt.parenR, /* possibleAsync */ false, ); + + // Handles invalid case: `f(a:b)` + this.tsCheckForInvalidTypeCasts(node.arguments); + node.typeParameters = typeArguments; return this.finishCallExpression(node, state.optionalChainMember); } else if (this.match(tt.backQuote)) { diff --git a/packages/babel-parser/test/fixtures/typescript/cast/invalid/input.ts b/packages/babel-parser/test/fixtures/typescript/cast/invalid/input.ts new file mode 100644 index 000000000000..6c18863fda3f --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/cast/invalid/input.ts @@ -0,0 +1,2 @@ +(a:b); +(a:b,c:d); diff --git a/packages/babel-parser/test/fixtures/typescript/cast/invalid/output.json b/packages/babel-parser/test/fixtures/typescript/cast/invalid/output.json new file mode 100644 index 000000000000..60e974ee9da9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/cast/invalid/output.json @@ -0,0 +1,106 @@ +{ + "type": "File", + "start":0,"end":17,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":10}}, + "errors": [ + "SyntaxError: Did not expect a type annotation here. (1:2)", + "SyntaxError: Did not expect a type annotation here. (2:2)", + "SyntaxError: Did not expect a type annotation here. (2:6)" + ], + "program": { + "type": "Program", + "start":0,"end":17,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":10}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}}, + "expression": { + "type": "TSTypeCastExpression", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "extra": { + "parenthesized": true, + "parenStart": 0 + }, + "expression": { + "type": "Identifier", + "start":1,"end":2,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":2},"identifierName":"a"}, + "name": "a" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":2,"end":4,"loc":{"start":{"line":1,"column":2},"end":{"line":1,"column":4}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":3,"end":4,"loc":{"start":{"line":1,"column":3},"end":{"line":1,"column":4}}, + "typeName": { + "type": "Identifier", + "start":3,"end":4,"loc":{"start":{"line":1,"column":3},"end":{"line":1,"column":4},"identifierName":"b"}, + "name": "b" + } + } + } + } + }, + { + "type": "ExpressionStatement", + "start":7,"end":17,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":10}}, + "expression": { + "type": "SequenceExpression", + "start":8,"end":15,"loc":{"start":{"line":2,"column":1},"end":{"line":2,"column":8}}, + "extra": { + "parenthesized": true, + "parenStart": 7 + }, + "expressions": [ + { + "type": "TSTypeCastExpression", + "start":8,"end":11,"loc":{"start":{"line":2,"column":1},"end":{"line":2,"column":4}}, + "expression": { + "type": "Identifier", + "start":8,"end":9,"loc":{"start":{"line":2,"column":1},"end":{"line":2,"column":2},"identifierName":"a"}, + "name": "a" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":9,"end":11,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":10,"end":11,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4}}, + "typeName": { + "type": "Identifier", + "start":10,"end":11,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"b"}, + "name": "b" + } + } + } + }, + { + "type": "TSTypeCastExpression", + "start":12,"end":15,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":8}}, + "expression": { + "type": "Identifier", + "start":12,"end":13,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":6},"identifierName":"c"}, + "name": "c" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":13,"end":15,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":8}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":14,"end":15,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}}, + "typeName": { + "type": "Identifier", + "start":14,"end":15,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8},"identifierName":"d"}, + "name": "d" + } + } + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/cast/parameter-typecast/output.json b/packages/babel-parser/test/fixtures/typescript/cast/parameter-typecast/output.json index d9518e74b169..397ff94c3c7d 100644 --- a/packages/babel-parser/test/fixtures/typescript/cast/parameter-typecast/output.json +++ b/packages/babel-parser/test/fixtures/typescript/cast/parameter-typecast/output.json @@ -2,8 +2,8 @@ "type": "File", "start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":14}}, "errors": [ - "SyntaxError: Did not expect a type annotation here. (1:5)", - "SyntaxError: Did not expect a type annotation here. (2:8)" + "SyntaxError: Did not expect a type annotation here. (1:6)", + "SyntaxError: Did not expect a type annotation here. (2:9)" ], "program": { "type": "Program",