Skip to content

Commit f308ac1

Browse files
committed
Do not parse template arguments in JavaScript files.
Fixes #36662.
1 parent 2cc5856 commit f308ac1

9 files changed

+69
-38
lines changed

src/compiler/parser.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -4540,7 +4540,7 @@ namespace ts {
45404540
}
45414541

45424542
const tagName = parseJsxElementName();
4543-
const typeArguments = tryParseTypeArguments();
4543+
const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined;
45444544
const attributes = parseJsxAttributes();
45454545

45464546
let node: JsxOpeningLikeElement;
@@ -4797,7 +4797,8 @@ namespace ts {
47974797
const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken);
47984798

47994799
// handle 'foo<<T>()'
4800-
if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) {
4800+
// parse template arguments only in TypeScript files (not in JavaScript files).
4801+
if ((contextFlags & NodeFlags.JavaScriptFile) === 0 && (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken)) {
48014802
// See if this is the start of a generic invocation. If so, consume it and
48024803
// keep checking for postfix expressions. Otherwise, it's just a '<' that's
48034804
// part of an arithmetic expression. Break out so we consume it higher in the
@@ -4854,6 +4855,11 @@ namespace ts {
48544855
}
48554856

48564857
function parseTypeArgumentsInExpression() {
4858+
if ((contextFlags & NodeFlags.JavaScriptFile) !== 0) {
4859+
// TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators.
4860+
return undefined;
4861+
}
4862+
48574863
if (reScanLessThanToken() !== SyntaxKind.LessThanToken) {
48584864
return undefined;
48594865
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Syntactic Diagnostics for file '/tests/cases/fourslash/getJavaScriptSyntacticDiagnostics14.ts':
2-
/tests/cases/fourslash/a.js(1,5): error TS8011: Type arguments can only be used in TypeScript files.
2+
/tests/cases/fourslash/a.js(1,13): error TS1109: Expression expected.
33

44

55
==== /tests/cases/fourslash/a.js (1 errors) ====
66
Foo<number>();
7-
~~~~~~
8-
!!! error TS8011: Type arguments can only be used in TypeScript files.
7+
~
8+
!!! error TS1109: Expression expected.
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
1-
tests/cases/compiler/a.jsx(1,5): error TS8011: Type arguments can only be used in TypeScript files.
2-
tests/cases/compiler/a.jsx(2,5): error TS8011: Type arguments can only be used in TypeScript files.
3-
tests/cases/compiler/a.jsx(3,6): error TS8011: Type arguments can only be used in TypeScript files.
4-
tests/cases/compiler/a.jsx(4,6): error TS8011: Type arguments can only be used in TypeScript files.
1+
tests/cases/compiler/a.jsx(1,13): error TS1109: Expression expected.
2+
tests/cases/compiler/a.jsx(4,5): error TS1003: Identifier expected.
3+
tests/cases/compiler/a.jsx(4,14): error TS17002: Expected corresponding JSX closing tag for 'number'.
4+
tests/cases/compiler/a.jsx(4,20): error TS2657: JSX expressions must have one parent element.
5+
tests/cases/compiler/a.jsx(5,5): error TS1003: Identifier expected.
6+
tests/cases/compiler/a.jsx(5,6): error TS17008: JSX element 'number' has no corresponding closing tag.
7+
tests/cases/compiler/a.jsx(6,1): error TS1005: '</' expected.
58

69

7-
==== tests/cases/compiler/a.jsx (4 errors) ====
10+
==== tests/cases/compiler/a.jsx (7 errors) ====
811
Foo<number>();
9-
~~~~~~
10-
!!! error TS8011: Type arguments can only be used in TypeScript files.
12+
~
13+
!!! error TS1109: Expression expected.
14+
Foo<number>(1);
1115
Foo<number>``;
12-
~~~~~~
13-
!!! error TS8011: Type arguments can only be used in TypeScript files.
1416
<Foo<number>></Foo>;
15-
~~~~~~
16-
!!! error TS8011: Type arguments can only be used in TypeScript files.
17+
~
18+
!!! error TS1003: Identifier expected.
19+
~~~~~~
20+
!!! error TS17002: Expected corresponding JSX closing tag for 'number'.
21+
~
22+
!!! error TS2657: JSX expressions must have one parent element.
1723
<Foo<number>/>;
24+
~
25+
!!! error TS1003: Identifier expected.
1826
~~~~~~
19-
!!! error TS8011: Type arguments can only be used in TypeScript files.
27+
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
28+
29+
30+
!!! error TS1005: '</' expected.
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//// [a.jsx]
22
Foo<number>();
3+
Foo<number>(1);
34
Foo<number>``;
45
<Foo<number>></Foo>;
5-
<Foo<number>/>;
6+
<Foo<number>/>;
7+
68

79
//// [a.js]
8-
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
9-
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
10-
return cooked;
11-
};
12-
Foo();
13-
Foo(__makeTemplateObject([""], [""]));
14-
<Foo></Foo>;
15-
<Foo />;
10+
Foo < number > ();
11+
Foo < number > (1);
12+
Foo < number > "";
13+
<Foo />, <number>></Foo>;
14+
<Foo />, <number>/>;
15+
</>;

tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.errors.txt

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
tests/cases/conformance/jsx/file.jsx(4,17): error TS8011: Type arguments can only be used in TypeScript files.
1+
tests/cases/conformance/jsx/file.jsx(4,9): error TS2695: Left side of comma operator is unused and has no side effects.
2+
tests/cases/conformance/jsx/file.jsx(4,16): error TS1003: Identifier expected.
3+
tests/cases/conformance/jsx/file.jsx(4,17): error TS2693: 'Prop' only refers to a type, but is being used as a value here.
4+
tests/cases/conformance/jsx/file.jsx(4,17): error TS17008: JSX element 'Prop' has no corresponding closing tag.
5+
tests/cases/conformance/jsx/file.jsx(5,1): error TS1005: '</' expected.
26

37

48
==== tests/cases/conformance/jsx/component.d.ts (0 errors) ====
@@ -12,11 +16,19 @@ tests/cases/conformance/jsx/file.jsx(4,17): error TS8011: Type arguments can onl
1216
b: string
1317
}
1418

15-
==== tests/cases/conformance/jsx/file.jsx (1 errors) ====
19+
==== tests/cases/conformance/jsx/file.jsx (5 errors) ====
1620
import { MyComp, Prop } from "./component";
1721
import * as React from "react";
1822

1923
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
24+
~~~~~~~
25+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
26+
~
27+
!!! error TS1003: Identifier expected.
2028
~~~~
21-
!!! error TS8011: Type arguments can only be used in TypeScript files.
22-
29+
!!! error TS2693: 'Prop' only refers to a type, but is being used as a value here.
30+
~~~~
31+
!!! error TS17008: JSX element 'Prop' has no corresponding closing tag.
32+
33+
34+
!!! error TS1005: '</' expected.

tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
2323
exports.__esModule = true;
2424
var component_1 = require("./component");
2525
var React = require("react");
26-
var x = <component_1.MyComp a={10} b="hi"/>; // error, no type arguments in js
26+
var x = <component_1.MyComp />, <Prop> a={10} b="hi" />; // error, no type arguments in js
27+
</>;

tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.symbols

-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,4 @@ import * as React from "react";
3636
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
3737
>x : Symbol(x, Decl(file.jsx, 3, 3))
3838
>MyComp : Symbol(MyComp, Decl(file.jsx, 0, 8))
39-
>Prop : Symbol(Prop, Decl(file.jsx, 0, 16))
40-
>a : Symbol(a, Decl(file.jsx, 3, 21))
41-
>b : Symbol(b, Decl(file.jsx, 3, 28))
4239

tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.types

+6-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ import * as React from "react";
3030

3131
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
3232
>x : JSX.Element
33-
><MyComp<Prop> a={10} b="hi" /> : JSX.Element
33+
><MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js : JSX.Element
34+
><MyComp : JSX.Element
3435
>MyComp : typeof MyComp
35-
>a : number
36+
><Prop> a={10} b="hi" />; // error, no type arguments in js : JSX.Element
37+
>Prop : any
3638
>10 : 10
37-
>b : string
39+
40+
> : any
3841

tests/cases/compiler/jsFileCompilationTypeArgumentSyntaxOfCall.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// @noTypesAndSymbols: true
33
// @filename: a.jsx
44
Foo<number>();
5+
Foo<number>(1);
56
Foo<number>``;
67
<Foo<number>></Foo>;
7-
<Foo<number>/>;
8+
<Foo<number>/>;

0 commit comments

Comments
 (0)