Skip to content

Commit 0ef9e8e

Browse files
authored
Ensure we treat "type assertions" as JSX within a unary expression (#52667)
1 parent bec0fda commit 0ef9e8e

18 files changed

+207
-0
lines changed

src/compiler/parser.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5648,6 +5648,11 @@ namespace Parser {
56485648
case SyntaxKind.VoidKeyword:
56495649
return parseVoidExpression();
56505650
case SyntaxKind.LessThanToken:
5651+
// Just like in parseUpdateExpression, we need to avoid parsing type assertions when
5652+
// in JSX and we see an expression like "+ <foo> bar".
5653+
if (languageVariant === LanguageVariant.JSX) {
5654+
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
5655+
}
56515656
// This is modified UnaryExpression grammar in TypeScript
56525657
// UnaryExpression (modified):
56535658
// < type > UnaryExpression
@@ -6163,6 +6168,7 @@ namespace Parser {
61636168
}
61646169

61656170
function parseTypeAssertion(): TypeAssertion {
6171+
Debug.assert(scriptKind === ScriptKind.TS, "Type assertions should never be parsed outside of TS; they should either be comparisons or JSX.");
61666172
const pos = getNodePos();
61676173
parseExpected(SyntaxKind.LessThanToken);
61686174
const type = parseType();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
2+
tests/cases/compiler/index.js(2,14): error TS17008: JSX element 'number' has no corresponding closing tag.
3+
tests/cases/compiler/index.js(3,1): error TS1005: '</' expected.
4+
5+
6+
==== tests/cases/compiler/index.js (3 errors) ====
7+
const x = "oops";
8+
const y = + <number> x;
9+
~~~~~~~~
10+
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
11+
~~~~~~
12+
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
13+
14+
15+
!!! error TS1005: '</' expected.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : Symbol(x, Decl(index.js, 0, 5))
4+
5+
const y = + <number> x;
6+
>y : Symbol(y, Decl(index.js, 1, 5))
7+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : "oops"
4+
>"oops" : "oops"
5+
6+
const y = + <number> x;
7+
>y : number
8+
>+ <number> x; : number
9+
><number> x; : any
10+
>number : any
11+
12+
> : any
13+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/compiler/index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag.
2+
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
3+
tests/cases/compiler/index.js(3,1): error TS1005: '</' expected.
4+
5+
6+
==== tests/cases/compiler/index.js (3 errors) ====
7+
const x = "oops";
8+
const y = + <> x;
9+
~~~
10+
!!! error TS17014: JSX fragment has no corresponding closing tag.
11+
~~
12+
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
13+
14+
15+
!!! error TS1005: '</' expected.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : Symbol(x, Decl(index.js, 0, 5))
4+
5+
const y = + <> x;
6+
>y : Symbol(y, Decl(index.js, 1, 5))
7+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : "oops"
4+
>"oops" : "oops"
5+
6+
const y = + <> x;
7+
>y : number
8+
>+ <> x; : number
9+
><> x; : any
10+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/compiler/index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
2+
tests/cases/compiler/index.js(2,14): error TS1003: Identifier expected.
3+
tests/cases/compiler/index.js(2,14): error TS2365: Operator '>' cannot be applied to types 'number' and 'string'.
4+
5+
6+
==== tests/cases/compiler/index.js (3 errors) ====
7+
const x = "oops";
8+
const y = + <1234> x;
9+
~
10+
!!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
11+
~~~~
12+
!!! error TS1003: Identifier expected.
13+
~~~~~~~
14+
!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'string'.
15+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : Symbol(x, Decl(index.js, 0, 5))
4+
5+
const y = + <1234> x;
6+
>y : Symbol(y, Decl(index.js, 1, 5))
7+
>x : Symbol(x, Decl(index.js, 0, 5))
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/compiler/index.js ===
2+
const x = "oops";
3+
>x : "oops"
4+
>"oops" : "oops"
5+
6+
const y = + <1234> x;
7+
>y : number
8+
>+ < : number
9+
>< : any
10+
> : any
11+
>1234> x : boolean
12+
>1234 : 1234
13+
>x : "oops"
14+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
tests/cases/compiler/index.tsx(3,14): error TS17008: JSX element 'number' has no corresponding closing tag.
2+
tests/cases/compiler/index.tsx(4,13): error TS17014: JSX fragment has no corresponding closing tag.
3+
tests/cases/compiler/index.tsx(5,14): error TS1003: Identifier expected.
4+
tests/cases/compiler/index.tsx(5,18): error TS1382: Unexpected token. Did you mean `{'>'}` or `&gt;`?
5+
tests/cases/compiler/index.tsx(6,1): error TS1005: '</' expected.
6+
7+
8+
==== tests/cases/compiler/index.tsx (5 errors) ====
9+
const x = "oops";
10+
11+
const a = + <number> x;
12+
~~~~~~
13+
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
14+
const b = + <> x;
15+
~~
16+
!!! error TS17014: JSX fragment has no corresponding closing tag.
17+
const c = + <1234> x;
18+
~~~~
19+
!!! error TS1003: Identifier expected.
20+
~
21+
!!! error TS1382: Unexpected token. Did you mean `{'>'}` or `&gt;`?
22+
23+
24+
!!! error TS1005: '</' expected.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [index.tsx]
2+
const x = "oops";
3+
4+
const a = + <number> x;
5+
const b = + <> x;
6+
const c = + <1234> x;
7+
8+
9+
//// [index.jsx]
10+
var x = "oops";
11+
var a = +<number> x;
12+
const b = + <> x;
13+
const c = + < />1234> x;
14+
</></>;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/index.tsx ===
2+
const x = "oops";
3+
>x : Symbol(x, Decl(index.tsx, 0, 5))
4+
5+
const a = + <number> x;
6+
>a : Symbol(a, Decl(index.tsx, 2, 5))
7+
8+
const b = + <> x;
9+
const c = + <1234> x;
10+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/index.tsx ===
2+
const x = "oops";
3+
>x : "oops"
4+
>"oops" : "oops"
5+
6+
const a = + <number> x;
7+
>a : number
8+
>+ <number> x;const b = + <> x;const c = + <1234> x; : number
9+
><number> x;const b = + <> x;const c = + <1234> x; : any
10+
>number : any
11+
12+
const b = + <> x;
13+
><> x;const c = + <1234> x; : any
14+
15+
const c = + <1234> x;
16+
>< : any
17+
> : any
18+
19+
> : any
20+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @filename: index.js
5+
6+
const x = "oops";
7+
const y = + <number> x;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @filename: index.js
5+
6+
const x = "oops";
7+
const y = + <> x;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @filename: index.js
5+
6+
const x = "oops";
7+
const y = + <1234> x;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @filename: index.tsx
2+
// @jsx: preserve
3+
4+
const x = "oops";
5+
6+
const a = + <number> x;
7+
const b = + <> x;
8+
const c = + <1234> x;

0 commit comments

Comments
 (0)