Skip to content

Commit dfe885b

Browse files
Properly re-scan > token in type argument list determination logic (#49560) (#49570)
* Properly re-scan '>' token in type argument list determination logic * Add regression test
1 parent 4d2983a commit dfe885b

File tree

6 files changed

+614
-2
lines changed

6 files changed

+614
-2
lines changed

src/compiler/parser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -5705,10 +5705,11 @@ namespace ts {
57055705
nextToken();
57065706

57075707
const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
5708-
if (!parseExpected(SyntaxKind.GreaterThanToken)) {
5708+
if (reScanGreaterToken() !== SyntaxKind.GreaterThanToken) {
57095709
// If it doesn't have the closing `>` then it's definitely not an type argument list.
57105710
return undefined;
57115711
}
5712+
nextToken();
57125713

57135714
// We successfully parsed a type argument list. The next token determines whether we want to
57145715
// treat it as such. If the type argument list is followed by `(` or a template literal, as in

tests/baselines/reference/instantiationExpressionErrors.errors.txt

+143-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,40 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr
88
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(26,24): error TS2558: Expected 0 type arguments, but got 1.
99
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(31,2): error TS2554: Expected 0 arguments, but got 1.
1010
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(35,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
11+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(48,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
12+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(49,1): error TS2304: Cannot find name 'let'.
13+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(49,5): error TS1005: ',' expected.
14+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(51,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
15+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,1): error TS2304: Cannot find name 'interface'.
16+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,11): error TS1005: ',' expected.
17+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,11): error TS7005: Variable 'I' implicitly has an 'any' type.
18+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,13): error TS1005: ',' expected.
19+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(54,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
20+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(55,6): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
21+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(57,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
22+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(57,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and '() => void'.
23+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(60,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
24+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(60,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'typeof C'.
25+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(63,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
26+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(64,1): error TS2304: Cannot find name 'bar'.
27+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(66,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
28+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(67,1): error TS2532: Object is possibly 'undefined'.
29+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(67,6): error TS2304: Cannot find name 'bar'.
30+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(70,27): error TS2693: 'string' only refers to a type, but is being used as a value here.
31+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(71,5): error TS2304: Cannot find name 'static'.
32+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(71,12): error TS1005: ';' expected.
33+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(75,27): error TS2693: 'string' only refers to a type, but is being used as a value here.
34+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(76,5): error TS2304: Cannot find name 'public'.
35+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(76,12): error TS1005: ';' expected.
36+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(80,28): error TS2693: 'string' only refers to a type, but is being used as a value here.
37+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(81,5): error TS2304: Cannot find name 'private'.
38+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(81,13): error TS1005: ';' expected.
39+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(85,30): error TS2693: 'string' only refers to a type, but is being used as a value here.
40+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(86,5): error TS2304: Cannot find name 'protected'.
41+
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(86,15): error TS1005: ';' expected.
1142

1243

13-
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (10 errors) ====
44+
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (41 errors) ====
1445
declare let f: { <T>(): T, g<U>(): U };
1546

1647
// Type arguments in member expressions
@@ -77,4 +108,115 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr
77108

78109
const x4 = f<true>
79110
if (true) {}
111+
112+
const x5 = f<true>
113+
~~~~~~
114+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
115+
let yy = 0;
116+
~~~
117+
!!! error TS2304: Cannot find name 'let'.
118+
~~
119+
!!! error TS1005: ',' expected.
120+
121+
const x6 = f<true>
122+
~~~~~~
123+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
124+
interface I {}
125+
~~~~~~~~~
126+
!!! error TS2304: Cannot find name 'interface'.
127+
~
128+
!!! error TS1005: ',' expected.
129+
~
130+
!!! error TS7005: Variable 'I' implicitly has an 'any' type.
131+
~
132+
!!! error TS1005: ',' expected.
133+
134+
let x10 = f<true>
135+
~~~~~~
136+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
137+
this.bar()
138+
~~~
139+
!!! error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
140+
141+
let x11 = f<true>
142+
~~~~~~
143+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
144+
~~~~~~~
145+
function bar() {}
146+
~~~~~~~~~~~~~~~~~
147+
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '() => void'.
148+
149+
let x12 = f<true>
150+
~~~~~~
151+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
152+
~~~~~~~
153+
class C {}
154+
~~~~~~~~~~
155+
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'typeof C'.
156+
157+
let x13 = f<true>
158+
~~~~~~
159+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
160+
bar()
161+
~~~
162+
!!! error TS2304: Cannot find name 'bar'.
163+
164+
let x14 = f<true>
165+
~~~~~~
166+
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
167+
void bar()
168+
~~~~~~~~~~
169+
!!! error TS2532: Object is possibly 'undefined'.
170+
~~~
171+
!!! error TS2304: Cannot find name 'bar'.
172+
173+
class C1 {
174+
static specialFoo = f<string>
175+
~~~~~~
176+
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
177+
static bar = 123
178+
~~~~~~
179+
!!! error TS2304: Cannot find name 'static'.
180+
~~~
181+
!!! error TS1005: ';' expected.
182+
}
183+
184+
class C2 {
185+
public specialFoo = f<string>
186+
~~~~~~
187+
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
188+
public bar = 123
189+
~~~~~~
190+
!!! error TS2304: Cannot find name 'public'.
191+
~~~
192+
!!! error TS1005: ';' expected.
193+
}
194+
195+
class C3 {
196+
private specialFoo = f<string>
197+
~~~~~~
198+
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
199+
private bar = 123
200+
~~~~~~~
201+
!!! error TS2304: Cannot find name 'private'.
202+
~~~
203+
!!! error TS1005: ';' expected.
204+
}
205+
206+
class C4 {
207+
protected specialFoo = f<string>
208+
~~~~~~
209+
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
210+
protected bar = 123
211+
~~~~~~~~~
212+
!!! error TS2304: Cannot find name 'protected'.
213+
~~~
214+
!!! error TS1005: ';' expected.
215+
}
216+
217+
// Repro from #49551
218+
219+
const enum MyVer { v1 = 1, v2 = 2 }
220+
let ver = 21
221+
const a = ver < (MyVer.v1 >= MyVer.v2 ? MyVer.v1 : MyVer.v2)
80222

tests/baselines/reference/instantiationExpressionErrors.js

+127
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,53 @@ true;
4545

4646
const x4 = f<true>
4747
if (true) {}
48+
49+
const x5 = f<true>
50+
let yy = 0;
51+
52+
const x6 = f<true>
53+
interface I {}
54+
55+
let x10 = f<true>
56+
this.bar()
57+
58+
let x11 = f<true>
59+
function bar() {}
60+
61+
let x12 = f<true>
62+
class C {}
63+
64+
let x13 = f<true>
65+
bar()
66+
67+
let x14 = f<true>
68+
void bar()
69+
70+
class C1 {
71+
static specialFoo = f<string>
72+
static bar = 123
73+
}
74+
75+
class C2 {
76+
public specialFoo = f<string>
77+
public bar = 123
78+
}
79+
80+
class C3 {
81+
private specialFoo = f<string>
82+
private bar = 123
83+
}
84+
85+
class C4 {
86+
protected specialFoo = f<string>
87+
protected bar = 123
88+
}
89+
90+
// Repro from #49551
91+
92+
const enum MyVer { v1 = 1, v2 = 2 }
93+
let ver = 21
94+
const a = ver < (MyVer.v1 >= MyVer.v2 ? MyVer.v1 : MyVer.v2)
4895

4996

5097
//// [instantiationExpressionErrors.js]
@@ -78,6 +125,57 @@ true;
78125
// Parsed as instantiation expression
79126
var x4 = (f);
80127
if (true) { }
128+
var x5 = f < true >
129+
let, yy = 0;
130+
var x6 = f < true >
131+
interface, I, _c = void 0;
132+
var x10 = f < true >
133+
this.bar();
134+
var x11 = f < true >
135+
function bar() { };
136+
var x12 = f < true > /** @class */ (function () {
137+
function C() {
138+
}
139+
return C;
140+
}());
141+
var x13 = f < true >
142+
bar();
143+
var x14 = f < true >
144+
void bar();
145+
var C1 = /** @class */ (function () {
146+
function C1() {
147+
this.bar = 123;
148+
}
149+
C1.specialFoo = f < string >
150+
static;
151+
return C1;
152+
}());
153+
var C2 = /** @class */ (function () {
154+
function C2() {
155+
this.specialFoo = f < string >
156+
public;
157+
this.bar = 123;
158+
}
159+
return C2;
160+
}());
161+
var C3 = /** @class */ (function () {
162+
function C3() {
163+
this.specialFoo = f < string >
164+
private;
165+
this.bar = 123;
166+
}
167+
return C3;
168+
}());
169+
var C4 = /** @class */ (function () {
170+
function C4() {
171+
this.specialFoo = f < string >
172+
protected;
173+
this.bar = 123;
174+
}
175+
return C4;
176+
}());
177+
var ver = 21;
178+
var a = ver < (1 /* MyVer.v1 */ >= 2 /* MyVer.v2 */ ? 1 /* MyVer.v1 */ : 2 /* MyVer.v2 */);
81179

82180

83181
//// [instantiationExpressionErrors.d.ts]
@@ -113,3 +211,32 @@ declare const x4: {
113211
(): true;
114212
g<U>(): U;
115213
};
214+
declare const x5: boolean, yy = 0;
215+
declare const x6: boolean, I: any;
216+
declare let x10: boolean;
217+
declare let x11: boolean;
218+
declare let x12: boolean;
219+
declare let x13: boolean;
220+
declare let x14: boolean;
221+
declare class C1 {
222+
static specialFoo: boolean;
223+
bar: number;
224+
}
225+
declare class C2 {
226+
specialFoo: boolean;
227+
bar: number;
228+
}
229+
declare class C3 {
230+
private specialFoo;
231+
bar: number;
232+
}
233+
declare class C4 {
234+
protected specialFoo: boolean;
235+
bar: number;
236+
}
237+
declare const enum MyVer {
238+
v1 = 1,
239+
v2 = 2
240+
}
241+
declare let ver: number;
242+
declare const a: boolean;

0 commit comments

Comments
 (0)