Ensure we treat "type assertions" as JSX within a unary expression (#52667)

This commit is contained in:
Jake Bailey 2023-02-09 11:34:47 -08:00 committed by GitHub
parent bec0fdac23
commit 0ef9e8eac9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 207 additions and 0 deletions

View File

@ -5648,6 +5648,11 @@ namespace Parser {
case SyntaxKind.VoidKeyword:
return parseVoidExpression();
case SyntaxKind.LessThanToken:
// Just like in parseUpdateExpression, we need to avoid parsing type assertions when
// in JSX and we see an expression like "+ <foo> bar".
if (languageVariant === LanguageVariant.JSX) {
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
}
// This is modified UnaryExpression grammar in TypeScript
// UnaryExpression (modified):
// < type > UnaryExpression
@ -6163,6 +6168,7 @@ namespace Parser {
}
function parseTypeAssertion(): TypeAssertion {
Debug.assert(scriptKind === ScriptKind.TS, "Type assertions should never be parsed outside of TS; they should either be comparisons or JSX.");
const pos = getNodePos();
parseExpected(SyntaxKind.LessThanToken);
const type = parseType();

View File

@ -0,0 +1,15 @@
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
tests/cases/compiler/index.js(2,14): error TS17008: JSX element 'number' has no corresponding closing tag.
tests/cases/compiler/index.js(3,1): error TS1005: '</' expected.
==== tests/cases/compiler/index.js (3 errors) ====
const x = "oops";
const y = + <number> x;
~~~~~~~~
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
~~~~~~
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
!!! error TS1005: '</' expected.

View File

@ -0,0 +1,7 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : Symbol(x, Decl(index.js, 0, 5))
const y = + <number> x;
>y : Symbol(y, Decl(index.js, 1, 5))

View File

@ -0,0 +1,13 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : "oops"
>"oops" : "oops"
const y = + <number> x;
>y : number
>+ <number> x; : number
><number> x; : any
>number : any
> : any

View File

@ -0,0 +1,15 @@
tests/cases/compiler/index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag.
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
tests/cases/compiler/index.js(3,1): error TS1005: '</' expected.
==== tests/cases/compiler/index.js (3 errors) ====
const x = "oops";
const y = + <> x;
~~~
!!! error TS17014: JSX fragment has no corresponding closing tag.
~~
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
!!! error TS1005: '</' expected.

View File

@ -0,0 +1,7 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : Symbol(x, Decl(index.js, 0, 5))
const y = + <> x;
>y : Symbol(y, Decl(index.js, 1, 5))

View File

@ -0,0 +1,10 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : "oops"
>"oops" : "oops"
const y = + <> x;
>y : number
>+ <> x; : number
><> x; : any

View File

@ -0,0 +1,15 @@
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
tests/cases/compiler/index.js(2,14): error TS1003: Identifier expected.
tests/cases/compiler/index.js(2,14): error TS2365: Operator '>' cannot be applied to types 'number' and 'string'.
==== tests/cases/compiler/index.js (3 errors) ====
const x = "oops";
const y = + <1234> x;
~
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
~~~~
!!! error TS1003: Identifier expected.
~~~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'string'.

View File

@ -0,0 +1,8 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : Symbol(x, Decl(index.js, 0, 5))
const y = + <1234> x;
>y : Symbol(y, Decl(index.js, 1, 5))
>x : Symbol(x, Decl(index.js, 0, 5))

View File

@ -0,0 +1,14 @@
=== tests/cases/compiler/index.js ===
const x = "oops";
>x : "oops"
>"oops" : "oops"
const y = + <1234> x;
>y : number
>+ < : number
>< : any
> : any
>1234> x : boolean
>1234 : 1234
>x : "oops"

View File

@ -0,0 +1,24 @@
tests/cases/compiler/index.tsx(3,14): error TS17008: JSX element 'number' has no corresponding closing tag.
tests/cases/compiler/index.tsx(4,13): error TS17014: JSX fragment has no corresponding closing tag.
tests/cases/compiler/index.tsx(5,14): error TS1003: Identifier expected.
tests/cases/compiler/index.tsx(5,18): error TS1382: Unexpected token. Did you mean `{'>'}` or `&gt;`?
tests/cases/compiler/index.tsx(6,1): error TS1005: '</' expected.
==== tests/cases/compiler/index.tsx (5 errors) ====
const x = "oops";
const a = + <number> x;
~~~~~~
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
const b = + <> x;
~~
!!! error TS17014: JSX fragment has no corresponding closing tag.
const c = + <1234> x;
~~~~
!!! error TS1003: Identifier expected.
~
!!! error TS1382: Unexpected token. Did you mean `{'>'}` or `&gt;`?
!!! error TS1005: '</' expected.

View File

@ -0,0 +1,14 @@
//// [index.tsx]
const x = "oops";
const a = + <number> x;
const b = + <> x;
const c = + <1234> x;
//// [index.jsx]
var x = "oops";
var a = +<number> x;
const b = + <> x;
const c = + < />1234> x;
</></>;

View File

@ -0,0 +1,10 @@
=== tests/cases/compiler/index.tsx ===
const x = "oops";
>x : Symbol(x, Decl(index.tsx, 0, 5))
const a = + <number> x;
>a : Symbol(a, Decl(index.tsx, 2, 5))
const b = + <> x;
const c = + <1234> x;

View File

@ -0,0 +1,20 @@
=== tests/cases/compiler/index.tsx ===
const x = "oops";
>x : "oops"
>"oops" : "oops"
const a = + <number> x;
>a : number
>+ <number> x;const b = + <> x;const c = + <1234> x; : number
><number> x;const b = + <> x;const c = + <1234> x; : any
>number : any
const b = + <> x;
><> x;const c = + <1234> x; : any
const c = + <1234> x;
>< : any
> : any
> : any

View File

@ -0,0 +1,7 @@
// @allowJs: true
// @noEmit: true
// @checkJs: true
// @filename: index.js
const x = "oops";
const y = + <number> x;

View File

@ -0,0 +1,7 @@
// @allowJs: true
// @noEmit: true
// @checkJs: true
// @filename: index.js
const x = "oops";
const y = + <> x;

View File

@ -0,0 +1,7 @@
// @allowJs: true
// @noEmit: true
// @checkJs: true
// @filename: index.js
const x = "oops";
const y = + <1234> x;

View File

@ -0,0 +1,8 @@
// @filename: index.tsx
// @jsx: preserve
const x = "oops";
const a = + <number> x;
const b = + <> x;
const c = + <1234> x;