From e91e142f396d673a69b2e611f5393ca2dacfe839 Mon Sep 17 00:00:00 2001 From: ahmad65saad Date: Sat, 10 Oct 2026 05:23:27 +0300 Subject: [PATCH 1/3] Add test for type arguments starting with '<<' --- ...enericArrowRatherThanLeftShift2.errors.txt | 246 ++++++++++++++++++ .../parseGenericArrowRatherThanLeftShift2.js | 87 +++++++ ...seGenericArrowRatherThanLeftShift2.symbols | 166 ++++++++++++ ...arseGenericArrowRatherThanLeftShift2.types | 206 +++++++++++++++ .../parseGenericArrowRatherThanLeftShift2.tsx | 46 ++++ 5 files changed, 751 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js create mode 100644 tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types create mode 100644 tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt new file mode 100644 index 0000000000000..e8463913d0206 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt @@ -0,0 +1,246 @@ +heritage.ts(7,21): error TS2314: Generic type 'I' requires 1 type argument(s). +heritage.ts(7,22): error TS1005: ',' expected. +heritage.ts(7,24): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(7,27): error TS2304: Cannot find name 'x'. +heritage.ts(7,28): error TS1005: ')' expected. +heritage.ts(7,30): error TS1434: Unexpected keyword or identifier. +heritage.ts(7,30): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(7,31): error TS1128: Declaration or statement expected. +heritage.ts(7,33): error TS1128: Declaration or statement expected. +heritage.ts(7,36): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(8,18): error TS2314: Generic type 'B' requires 1 type argument(s). +heritage.ts(8,19): error TS1005: ',' expected. +heritage.ts(8,21): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(8,24): error TS2304: Cannot find name 'x'. +heritage.ts(8,25): error TS1005: ')' expected. +heritage.ts(8,27): error TS1434: Unexpected keyword or identifier. +heritage.ts(8,27): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(8,28): error TS1128: Declaration or statement expected. +heritage.ts(8,30): error TS1128: Declaration or statement expected. +heritage.ts(8,33): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +heritage.ts(9,26): error TS2314: Generic type 'B' requires 1 type argument(s). +heritage.ts(9,29): error TS1005: ',' expected. +heritage.ts(9,31): error TS2448: Block-scoped variable 'T' used before its declaration. +heritage.ts(9,34): error TS2304: Cannot find name 'x'. +heritage.ts(9,35): error TS1005: ')' expected. +heritage.ts(9,37): error TS2451: Cannot redeclare block-scoped variable 'T'. +heritage.ts(9,37): error TS7005: Variable 'T' implicitly has an 'any' type. +heritage.ts(9,38): error TS1005: ',' expected. +heritage.ts(9,40): error TS1005: ';' expected. +heritage.ts(10,22): error TS2314: Generic type 'J' requires 1 type argument(s). +heritage.ts(10,23): error TS1005: ',' expected. +heritage.ts(10,28): error TS2304: Cannot find name 'x'. +heritage.ts(10,29): error TS1005: ')' expected. +heritage.ts(10,31): error TS1434: Unexpected keyword or identifier. +heritage.ts(10,32): error TS1128: Declaration or statement expected. +heritage.ts(10,34): error TS1128: Declaration or statement expected. +heritage.ts(11,19): error TS1005: ';' expected. +jsx.tsx(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +jsx.tsx(9,13): error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. +jsx.tsx(9,17): error TS1003: Identifier expected. +jsx.tsx(9,22): error TS2304: Cannot find name 'x'. +jsx.tsx(9,23): error TS1005: ')' expected. +jsx.tsx(9,25): error TS2451: Cannot redeclare block-scoped variable 'T'. +jsx.tsx(9,25): error TS7005: Variable 'T' implicitly has an 'any' type. +jsx.tsx(9,26): error TS1005: ',' expected. +jsx.tsx(9,28): error TS1005: ';' expected. +jsx.tsx(9,34): error TS2304: Cannot find name 'value'. +jsx.tsx(9,39): error TS1005: ';' expected. +jsx.tsx(9,44): error TS1161: Unterminated regular expression literal. +jsx.tsx(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +jsx.tsx(10,13): error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. +jsx.tsx(10,17): error TS1003: Identifier expected. +jsx.tsx(10,22): error TS2304: Cannot find name 'x'. +jsx.tsx(10,23): error TS1005: ')' expected. +jsx.tsx(10,25): error TS2451: Cannot redeclare block-scoped variable 'T'. +jsx.tsx(10,25): error TS7005: Variable 'T' implicitly has an 'any' type. +jsx.tsx(10,26): error TS1005: ',' expected. +jsx.tsx(10,28): error TS1005: ';' expected. +jsx.tsx(10,34): error TS2304: Cannot find name 'value'. +jsx.tsx(10,39): error TS1005: ';' expected. +jsx.tsx(10,43): error TS1109: Expression expected. +jsx.tsx(10,44): error TS1109: Expression expected. +jsx.tsx(10,51): error TS1109: Expression expected. + + +==== heritage.ts (38 errors) ==== + declare const f: (x: T) => T; + declare function g(): typeof B; + declare class B {} + interface I {} + interface J {} + + class C1 implements I<(x: T) => T> {} + ~ +!!! error TS2314: Generic type 'I' requires 1 type argument(s). + ~~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS1434: Unexpected keyword or identifier. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + ~ +!!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS1128: Declaration or statement expected. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + class C2 extends B<(x: T) => T> {} + ~ +!!! error TS2314: Generic type 'B' requires 1 type argument(s). + ~~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS1434: Unexpected keyword or identifier. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + ~ +!!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS1128: Declaration or statement expected. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + const C3 = class extends g()<(x: T) => T> {}; + ~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + ~~~ +!!! error TS2314: Generic type 'B' requires 1 type argument(s). + ~~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2448: Block-scoped variable 'T' used before its declaration. +!!! related TS2728 heritage.ts:9:37: 'T' is declared here. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'T'. +!!! related TS6203 jsx.tsx:9:25: 'T' was also declared here. + ~ +!!! error TS7005: Variable 'T' implicitly has an 'any' type. + ~ +!!! error TS1005: ',' expected. + ~~ +!!! error TS1005: ';' expected. + interface I2 extends J<(x: T) => T> {} + ~ +!!! error TS2314: Generic type 'J' requires 1 type argument(s). + ~~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS1434: Unexpected keyword or identifier. + ~ +!!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS1128: Declaration or statement expected. + type A1 = typeof f<(x: T) => T>; + ~~ +!!! error TS1005: ';' expected. + + const e1 = f<(x: T) => T>; + const e2 = f<(x: T) => T>(f); + + // `<<` is still a left shift in expressions. + declare let n: number; + const s1 = n << 2; + const s2 = n< n; + + // `<<` after a type query in an expression is still a left shift. + declare const a: any; + const s4 = a as typeof n << 1; + const s5 = a satisfies typeof n << 1; + +==== jsx.tsx (26 errors) ==== + declare namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { x?: number }; + } + } + declare function Comp

(props: { value: P }): JSX.Element; + + const j1 = (x: T) => T> value={f} />; + ~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + ~~~~ +!!! error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. +!!! related TS2728 jsx.tsx:7:35: 'value' is declared here. + ~~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'T'. +!!! related TS6203 heritage.ts:9:37: 'T' was also declared here. + ~ +!!! error TS7005: Variable 'T' implicitly has an 'any' type. + ~ +!!! error TS1005: ',' expected. + ~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'value'. + ~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS1161: Unterminated regular expression literal. + const j2 = (x: T) => T> value={f}>; + ~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + ~~~~ +!!! error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. +!!! related TS2728 jsx.tsx:7:35: 'value' is declared here. + ~~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'x'. + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'T'. + ~ +!!! error TS7005: Variable 'T' implicitly has an 'any' type. + ~ +!!! error TS1005: ',' expected. + ~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'value'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1109: Expression expected. + ~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + const j3 =

; + const j4 =
; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js new file mode 100644 index 0000000000000..a7ea4e1741b37 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js @@ -0,0 +1,87 @@ +//// [tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx] //// + +//// [heritage.ts] +declare const f: (x: T) => T; +declare function g(): typeof B; +declare class B {} +interface I {} +interface J {} + +class C1 implements I<(x: T) => T> {} +class C2 extends B<(x: T) => T> {} +const C3 = class extends g()<(x: T) => T> {}; +interface I2 extends J<(x: T) => T> {} +type A1 = typeof f<(x: T) => T>; + +const e1 = f<(x: T) => T>; +const e2 = f<(x: T) => T>(f); + +// `<<` is still a left shift in expressions. +declare let n: number; +const s1 = n << 2; +const s2 = n< n; + +// `<<` after a type query in an expression is still a left shift. +declare const a: any; +const s4 = a as typeof n << 1; +const s5 = a satisfies typeof n << 1; + +//// [jsx.tsx] +declare namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { x?: number }; + } +} +declare function Comp

(props: { value: P }): JSX.Element; + +const j1 = (x: T) => T> value={f} />; +const j2 = (x: T) => T> value={f}>; +const j3 =

; +const j4 =
; + + +//// [heritage.js] +"use strict"; +class C1 { +} + << T > (x); +T; +T > {}; +class C2 extends B { +} + << T > (x); +T; +T > {}; +const C3 = class extends g() { +} << T > (x), T; +T > {}; + << T > (x); +T; +T > {}; +; +const e1 = f; +const e2 = f(f); +const s1 = n << 2; +const s2 = n << n; +const s3 = (n << n) > n; +const s4 = a << 1; +const s5 = a << 1; +//// [jsx.jsx] +"use strict"; +const j1 = << T > (x), T; +T > value; +{ + f; +} +/>; +const j2 = << T > (x), T; +T > value; +{ + f; +} + > ; +Comp > ; +const j3 =
; +const j4 =
; diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols new file mode 100644 index 0000000000000..e7cd2c09f15be --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols @@ -0,0 +1,166 @@ +//// [tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx] //// + +=== heritage.ts === +declare const f: (x: T) => T; +>f : Symbol(f, Decl(heritage.ts, 0, 13)) +>T : Symbol(T, Decl(heritage.ts, 0, 18)) +>x : Symbol(x, Decl(heritage.ts, 0, 21)) +>T : Symbol(T, Decl(heritage.ts, 0, 18)) +>T : Symbol(T, Decl(heritage.ts, 0, 18)) + +declare function g(): typeof B; +>g : Symbol(g, Decl(heritage.ts, 0, 32)) +>B : Symbol(B, Decl(heritage.ts, 1, 31)) + +declare class B {} +>B : Symbol(B, Decl(heritage.ts, 1, 31)) +>F : Symbol(F, Decl(heritage.ts, 2, 16)) + +interface I {} +>I : Symbol(I, Decl(heritage.ts, 2, 21)) +>F : Symbol(F, Decl(heritage.ts, 3, 12)) + +interface J {} +>J : Symbol(J, Decl(heritage.ts, 3, 17)) +>F : Symbol(F, Decl(heritage.ts, 4, 12)) + +class C1 implements I<(x: T) => T> {} +>C1 : Symbol(C1, Decl(heritage.ts, 4, 17)) +>I : Symbol(I, Decl(heritage.ts, 2, 21)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) + +class C2 extends B<(x: T) => T> {} +>C2 : Symbol(C2, Decl(heritage.ts, 6, 40)) +>B : Symbol(B, Decl(heritage.ts, 1, 31)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) + +const C3 = class extends g()<(x: T) => T> {}; +>C3 : Symbol(C3, Decl(heritage.ts, 8, 5)) +>g : Symbol(g, Decl(heritage.ts, 0, 32)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) + +interface I2 extends J<(x: T) => T> {} +>I2 : Symbol(I2, Decl(heritage.ts, 8, 48)) +>J : Symbol(J, Decl(heritage.ts, 3, 17)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) + +type A1 = typeof f<(x: T) => T>; +>A1 : Symbol(A1, Decl(heritage.ts, 9, 41)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) +>T : Symbol(T, Decl(heritage.ts, 10, 20)) +>x : Symbol(x, Decl(heritage.ts, 10, 23)) +>T : Symbol(T, Decl(heritage.ts, 10, 20)) +>T : Symbol(T, Decl(heritage.ts, 10, 20)) + +const e1 = f<(x: T) => T>; +>e1 : Symbol(e1, Decl(heritage.ts, 12, 5)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) +>T : Symbol(T, Decl(heritage.ts, 12, 14)) +>x : Symbol(x, Decl(heritage.ts, 12, 17)) +>T : Symbol(T, Decl(heritage.ts, 12, 14)) +>T : Symbol(T, Decl(heritage.ts, 12, 14)) + +const e2 = f<(x: T) => T>(f); +>e2 : Symbol(e2, Decl(heritage.ts, 13, 5)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) +>T : Symbol(T, Decl(heritage.ts, 13, 14)) +>x : Symbol(x, Decl(heritage.ts, 13, 17)) +>T : Symbol(T, Decl(heritage.ts, 13, 14)) +>T : Symbol(T, Decl(heritage.ts, 13, 14)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) + +// `<<` is still a left shift in expressions. +declare let n: number; +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +const s1 = n << 2; +>s1 : Symbol(s1, Decl(heritage.ts, 17, 5)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +const s2 = n<s2 : Symbol(s2, Decl(heritage.ts, 18, 5)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +const s3 = (n< n; +>s3 : Symbol(s3, Decl(heritage.ts, 19, 5)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +// `<<` after a type query in an expression is still a left shift. +declare const a: any; +>a : Symbol(a, Decl(heritage.ts, 22, 13)) + +const s4 = a as typeof n << 1; +>s4 : Symbol(s4, Decl(heritage.ts, 23, 5)) +>a : Symbol(a, Decl(heritage.ts, 22, 13)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +const s5 = a satisfies typeof n << 1; +>s5 : Symbol(s5, Decl(heritage.ts, 24, 5)) +>a : Symbol(a, Decl(heritage.ts, 22, 13)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +=== jsx.tsx === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(jsx.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(jsx.tsx, 0, 23)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(jsx.tsx, 1, 24)) + + div: { x?: number }; +>div : Symbol(IntrinsicElements.div, Decl(jsx.tsx, 2, 33)) +>x : Symbol(x, Decl(jsx.tsx, 3, 14)) + } +} +declare function Comp

(props: { value: P }): JSX.Element; +>Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) +>P : Symbol(P, Decl(jsx.tsx, 6, 22)) +>props : Symbol(props, Decl(jsx.tsx, 6, 25)) +>value : Symbol(value, Decl(jsx.tsx, 6, 33)) +>P : Symbol(P, Decl(jsx.tsx, 6, 22)) +>JSX : Symbol(JSX, Decl(jsx.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(jsx.tsx, 0, 23)) + +const j1 = (x: T) => T> value={f} />; +>j1 : Symbol(j1, Decl(jsx.tsx, 8, 5)) +>Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(jsx.tsx, 8, 23)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) + +const j2 = (x: T) => T> value={f}>; +>j2 : Symbol(j2, Decl(jsx.tsx, 9, 5)) +>Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(jsx.tsx, 9, 23)) +>T : Symbol(T, Decl(heritage.ts, 8, 35)) +>f : Symbol(f, Decl(heritage.ts, 0, 13)) +>Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) + +const j3 =

; +>j3 : Symbol(j3, Decl(jsx.tsx, 10, 5)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(jsx.tsx, 2, 33)) +>x : Symbol(x, Decl(jsx.tsx, 10, 15)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + +const j4 =
; +>j4 : Symbol(j4, Decl(jsx.tsx, 11, 5)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(jsx.tsx, 2, 33)) +>x : Symbol(x, Decl(jsx.tsx, 11, 15)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) +>n : Symbol(n, Decl(heritage.ts, 16, 11)) + diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types new file mode 100644 index 0000000000000..56fc59f25f60c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types @@ -0,0 +1,206 @@ +//// [tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx] //// + +=== heritage.ts === +declare const f: (x: T) => T; +>f : (x: T) => T +>x : T + +declare function g(): typeof B; +>g : () => typeof B +>B : typeof B + +declare class B {} +>B : B + +interface I {} +interface J {} + +class C1 implements I<(x: T) => T> {} +>C1 : C1 +><(x : boolean +>< : any +>T : any +>(x : any +>x : any +>T : any +>T> {} : boolean +>T : any +>{} : {} + +class C2 extends B<(x: T) => T> {} +>C2 : C2 +>B : typeof B +><(x : boolean +>< : any +>T : any +>(x : any +>x : any +>T : any +>T> {} : boolean +>T : any +>{} : {} + +const C3 = class extends g()<(x: T) => T> {}; +>C3 : boolean +>class extends g()<(x : boolean +>class extends g()<class extends g() : typeof (Anonymous class) +>g() : typeof B +>g : () => typeof B +>T : any +>(x : any +>x : any +>T : any +>T> {} : boolean +>T : any +>{} : {} + +interface I2 extends J<(x: T) => T> {} +><(x : boolean +>< : any +>T : any +>(x : any +>x : any +>T : any +>T> {} : boolean +>T : any +>{} : {} + +type A1 = typeof f<(x: T) => T>; +>A1 : (x: T) => T +>f : (x: T) => T +><(x: T) => T> : any +> : any +>x : T + +const e1 = f<(x: T) => T>; +>e1 : (x: (x: T) => T) => (x: T) => T +>f<(x: T) => T> : (x: (x: T) => T) => (x: T) => T +>f : (x: T) => T +>x : T + +const e2 = f<(x: T) => T>(f); +>e2 : (x: T) => T +>f<(x: T) => T>(f) : (x: T) => T +>f : (x: T) => T +>x : T +>f : (x: T) => T + +// `<<` is still a left shift in expressions. +declare let n: number; +>n : number + +const s1 = n << 2; +>s1 : number +>n << 2 : number +>n : number +>2 : 2 + +const s2 = n<s2 : number +>n<n : number +>n : number + +const s3 = (n< n; +>s3 : boolean +>(n< n : boolean +>(n<n<n : number +>n : number +>n : number + +// `<<` after a type query in an expression is still a left shift. +declare const a: any; +>a : any + +const s4 = a as typeof n << 1; +>s4 : number +>a as typeof n << 1 : number +>a as typeof n : number +>a : any +>n : number +>1 : 1 + +const s5 = a satisfies typeof n << 1; +>s5 : number +>a satisfies typeof n << 1 : number +>a satisfies typeof n : any +>a : any +>n : number +>1 : 1 + +=== jsx.tsx === +declare namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { x?: number }; +>div : { x?: number; } +>x : number | undefined + } +} +declare function Comp

(props: { value: P }): JSX.Element; +>Comp :

(props: { value: P; }) => JSX.Element +>props : { value: P; } +>value : P +>JSX : any + +const j1 = (x: T) => T> value={f} />; +>j1 : boolean +>(x : boolean +>Comp :

(props: { value: P; }) => JSX.Element +>T : any +>(x : any +>x : any +>T : any +>T> value : boolean +>T : any +>value : any +>f : (x: T) => T +>/> : RegExp + +const j2 = (x: T) => T> value={f}>; +>j2 : boolean +>(x : boolean +>Comp :

(props: { value: P; }) => JSX.Element +>T : any +>(x : any +>x : any +>T : any +>T> value : boolean +>T : any +>value : any +>f : (x: T) => T +>> : boolean +> : any +> : any +>Comp> : boolean +>Comp :

(props: { value: P; }) => JSX.Element +> : any + +const j3 =

; +>j3 : JSX.Element +>
: JSX.Element +>div : any +>x : number +>n << 1 : number +>n : number +>1 : 1 + +const j4 =
; +>j4 : JSX.Element +>
: JSX.Element +>div : any +>x : number +>n<n : number +>n : number + diff --git a/tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx b/tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx new file mode 100644 index 0000000000000..fc627b4046a6f --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift2.tsx @@ -0,0 +1,46 @@ +// @target: es2015 +// @jsx: preserve +// @strict: true + +// https://github.com/microsoft/TypeScript/issues/47410 + +// @filename: heritage.ts +declare const f: (x: T) => T; +declare function g(): typeof B; +declare class B {} +interface I {} +interface J {} + +class C1 implements I<(x: T) => T> {} +class C2 extends B<(x: T) => T> {} +const C3 = class extends g()<(x: T) => T> {}; +interface I2 extends J<(x: T) => T> {} +type A1 = typeof f<(x: T) => T>; + +const e1 = f<(x: T) => T>; +const e2 = f<(x: T) => T>(f); + +// `<<` is still a left shift in expressions. +declare let n: number; +const s1 = n << 2; +const s2 = n< n; + +// `<<` after a type query in an expression is still a left shift. +declare const a: any; +const s4 = a as typeof n << 1; +const s5 = a satisfies typeof n << 1; + +// @filename: jsx.tsx +declare namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { x?: number }; + } +} +declare function Comp

(props: { value: P }): JSX.Element; + +const j1 = (x: T) => T> value={f} />; +const j2 = (x: T) => T> value={f}>; +const j3 =

; +const j4 =
; From 7f7a6215e3e50eebd95b9a97f6238849df7cf441 Mon Sep 17 00:00:00 2001 From: ahmad65saad Date: Sat, 10 Oct 2026 05:43:06 +0300 Subject: [PATCH 2/3] Re-scan '<<' when parsing type arguments parseTypeArguments only checked for a '<' token, so a type argument list whose first type starts with '<' (e.g. a generic function type) was scanned as '<<' and never parsed. This affected heritage clauses, typeof type queries, and JSX opening elements. Re-scan the token first, as the type reference and expression paths already do. In a typeof type query, '<<' can also be a left shift following a type in an expression, as in `x as typeof y << 1`, which already compiles. There the type arguments are parsed speculatively and only kept if they parse without errors; otherwise the '<<' is left alone. Fixes #47410 --- tsc/internal/parser/parser.go | 16 +- ...enericArrowRatherThanLeftShift2.errors.txt | 246 ------------------ .../parseGenericArrowRatherThanLeftShift2.js | 28 +- ...seGenericArrowRatherThanLeftShift2.symbols | 44 ++-- ...arseGenericArrowRatherThanLeftShift2.types | 91 ++----- 5 files changed, 60 insertions(+), 365 deletions(-) delete mode 100644 tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index c670d64ad21c2..98cb7edcb821d 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -3086,7 +3086,7 @@ func (p *Parser) parseTypeArgumentsOfTypeReference() *ast.NodeList { } func (p *Parser) parseTypeArguments() *ast.NodeList { - if p.token == ast.KindLessThanToken { + if p.reScanLessThanToken() == ast.KindLessThanToken { return p.parseBracketedList(PCTypeArguments, (*Parser).parseType, ast.KindLessThanToken, ast.KindGreaterThanToken) } return nil @@ -3189,7 +3189,19 @@ func (p *Parser) parseTypeQuery() *ast.Node { // Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression var typeArguments *ast.NodeList if !p.hasPrecedingLineBreak() { - typeArguments = p.parseTypeArguments() + if p.token == ast.KindLessThanLessThanToken { + // `<<` may start type arguments whose first type is generic (`typeof f<(x: T) => T>`), but it + // may also be a left shift following a type in an expression (`x as typeof y << 1`). Only treat it + // as type arguments if they parse without errors. + state := p.mark() + typeArguments = p.parseTypeArguments() + if len(p.diagnostics) != state.diagnosticsLen { + p.rewind(state) + typeArguments = nil + } + } else { + typeArguments = p.parseTypeArguments() + } } return p.finishNode(p.factory.NewTypeQueryNode(entityName, typeArguments), pos) } diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt deleted file mode 100644 index e8463913d0206..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.errors.txt +++ /dev/null @@ -1,246 +0,0 @@ -heritage.ts(7,21): error TS2314: Generic type 'I' requires 1 type argument(s). -heritage.ts(7,22): error TS1005: ',' expected. -heritage.ts(7,24): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(7,27): error TS2304: Cannot find name 'x'. -heritage.ts(7,28): error TS1005: ')' expected. -heritage.ts(7,30): error TS1434: Unexpected keyword or identifier. -heritage.ts(7,30): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(7,31): error TS1128: Declaration or statement expected. -heritage.ts(7,33): error TS1128: Declaration or statement expected. -heritage.ts(7,36): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(8,18): error TS2314: Generic type 'B' requires 1 type argument(s). -heritage.ts(8,19): error TS1005: ',' expected. -heritage.ts(8,21): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(8,24): error TS2304: Cannot find name 'x'. -heritage.ts(8,25): error TS1005: ')' expected. -heritage.ts(8,27): error TS1434: Unexpected keyword or identifier. -heritage.ts(8,27): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(8,28): error TS1128: Declaration or statement expected. -heritage.ts(8,30): error TS1128: Declaration or statement expected. -heritage.ts(8,33): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -heritage.ts(9,26): error TS2314: Generic type 'B' requires 1 type argument(s). -heritage.ts(9,29): error TS1005: ',' expected. -heritage.ts(9,31): error TS2448: Block-scoped variable 'T' used before its declaration. -heritage.ts(9,34): error TS2304: Cannot find name 'x'. -heritage.ts(9,35): error TS1005: ')' expected. -heritage.ts(9,37): error TS2451: Cannot redeclare block-scoped variable 'T'. -heritage.ts(9,37): error TS7005: Variable 'T' implicitly has an 'any' type. -heritage.ts(9,38): error TS1005: ',' expected. -heritage.ts(9,40): error TS1005: ';' expected. -heritage.ts(10,22): error TS2314: Generic type 'J' requires 1 type argument(s). -heritage.ts(10,23): error TS1005: ',' expected. -heritage.ts(10,28): error TS2304: Cannot find name 'x'. -heritage.ts(10,29): error TS1005: ')' expected. -heritage.ts(10,31): error TS1434: Unexpected keyword or identifier. -heritage.ts(10,32): error TS1128: Declaration or statement expected. -heritage.ts(10,34): error TS1128: Declaration or statement expected. -heritage.ts(11,19): error TS1005: ';' expected. -jsx.tsx(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -jsx.tsx(9,13): error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. -jsx.tsx(9,17): error TS1003: Identifier expected. -jsx.tsx(9,22): error TS2304: Cannot find name 'x'. -jsx.tsx(9,23): error TS1005: ')' expected. -jsx.tsx(9,25): error TS2451: Cannot redeclare block-scoped variable 'T'. -jsx.tsx(9,25): error TS7005: Variable 'T' implicitly has an 'any' type. -jsx.tsx(9,26): error TS1005: ',' expected. -jsx.tsx(9,28): error TS1005: ';' expected. -jsx.tsx(9,34): error TS2304: Cannot find name 'value'. -jsx.tsx(9,39): error TS1005: ';' expected. -jsx.tsx(9,44): error TS1161: Unterminated regular expression literal. -jsx.tsx(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -jsx.tsx(10,13): error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. -jsx.tsx(10,17): error TS1003: Identifier expected. -jsx.tsx(10,22): error TS2304: Cannot find name 'x'. -jsx.tsx(10,23): error TS1005: ')' expected. -jsx.tsx(10,25): error TS2451: Cannot redeclare block-scoped variable 'T'. -jsx.tsx(10,25): error TS7005: Variable 'T' implicitly has an 'any' type. -jsx.tsx(10,26): error TS1005: ',' expected. -jsx.tsx(10,28): error TS1005: ';' expected. -jsx.tsx(10,34): error TS2304: Cannot find name 'value'. -jsx.tsx(10,39): error TS1005: ';' expected. -jsx.tsx(10,43): error TS1109: Expression expected. -jsx.tsx(10,44): error TS1109: Expression expected. -jsx.tsx(10,51): error TS1109: Expression expected. - - -==== heritage.ts (38 errors) ==== - declare const f: (x: T) => T; - declare function g(): typeof B; - declare class B {} - interface I {} - interface J {} - - class C1 implements I<(x: T) => T> {} - ~ -!!! error TS2314: Generic type 'I' requires 1 type argument(s). - ~~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS1434: Unexpected keyword or identifier. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - ~ -!!! error TS1128: Declaration or statement expected. - ~~ -!!! error TS1128: Declaration or statement expected. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - class C2 extends B<(x: T) => T> {} - ~ -!!! error TS2314: Generic type 'B' requires 1 type argument(s). - ~~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS1434: Unexpected keyword or identifier. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - ~ -!!! error TS1128: Declaration or statement expected. - ~~ -!!! error TS1128: Declaration or statement expected. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - const C3 = class extends g()<(x: T) => T> {}; - ~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. - ~~~ -!!! error TS2314: Generic type 'B' requires 1 type argument(s). - ~~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2448: Block-scoped variable 'T' used before its declaration. -!!! related TS2728 heritage.ts:9:37: 'T' is declared here. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS2451: Cannot redeclare block-scoped variable 'T'. -!!! related TS6203 jsx.tsx:9:25: 'T' was also declared here. - ~ -!!! error TS7005: Variable 'T' implicitly has an 'any' type. - ~ -!!! error TS1005: ',' expected. - ~~ -!!! error TS1005: ';' expected. - interface I2 extends J<(x: T) => T> {} - ~ -!!! error TS2314: Generic type 'J' requires 1 type argument(s). - ~~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS1434: Unexpected keyword or identifier. - ~ -!!! error TS1128: Declaration or statement expected. - ~~ -!!! error TS1128: Declaration or statement expected. - type A1 = typeof f<(x: T) => T>; - ~~ -!!! error TS1005: ';' expected. - - const e1 = f<(x: T) => T>; - const e2 = f<(x: T) => T>(f); - - // `<<` is still a left shift in expressions. - declare let n: number; - const s1 = n << 2; - const s2 = n< n; - - // `<<` after a type query in an expression is still a left shift. - declare const a: any; - const s4 = a as typeof n << 1; - const s5 = a satisfies typeof n << 1; - -==== jsx.tsx (26 errors) ==== - declare namespace JSX { - interface Element {} - interface IntrinsicElements { - div: { x?: number }; - } - } - declare function Comp

(props: { value: P }): JSX.Element; - - const j1 = (x: T) => T> value={f} />; - ~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. - ~~~~ -!!! error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. -!!! related TS2728 jsx.tsx:7:35: 'value' is declared here. - ~~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS2451: Cannot redeclare block-scoped variable 'T'. -!!! related TS6203 heritage.ts:9:37: 'T' was also declared here. - ~ -!!! error TS7005: Variable 'T' implicitly has an 'any' type. - ~ -!!! error TS1005: ',' expected. - ~~ -!!! error TS1005: ';' expected. - ~~~~~ -!!! error TS2304: Cannot find name 'value'. - ~ -!!! error TS1005: ';' expected. - ~~ -!!! error TS1161: Unterminated regular expression literal. - const j2 = (x: T) => T> value={f}>; - ~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. - ~~~~ -!!! error TS2741: Property 'value' is missing in type '{}' but required in type '{ value: unknown; }'. -!!! related TS2728 jsx.tsx:7:35: 'value' is declared here. - ~~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS2451: Cannot redeclare block-scoped variable 'T'. - ~ -!!! error TS7005: Variable 'T' implicitly has an 'any' type. - ~ -!!! error TS1005: ',' expected. - ~~ -!!! error TS1005: ';' expected. - ~~~~~ -!!! error TS2304: Cannot find name 'value'. - ~ -!!! error TS1005: ';' expected. - ~ -!!! error TS1109: Expression expected. - ~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1109: Expression expected. - const j3 =

; - const j4 =
; - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js index a7ea4e1741b37..1fca9a442a0fe 100644 --- a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.js @@ -46,21 +46,10 @@ const j4 =
; "use strict"; class C1 { } - << T > (x); -T; -T > {}; class C2 extends B { } - << T > (x); -T; -T > {}; const C3 = class extends g() { -} << T > (x), T; -T > {}; - << T > (x); -T; -T > {}; -; +}; const e1 = f; const e2 = f(f); const s1 = n << 2; @@ -70,18 +59,7 @@ const s4 = a << 1; const s5 = a << 1; //// [jsx.jsx] "use strict"; -const j1 = << T > (x), T; -T > value; -{ - f; -} -/>; -const j2 = << T > (x), T; -T > value; -{ - f; -} - > ; -Comp > ; +const j1 = ; +const j2 = ; const j3 =
; const j4 =
; diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols index e7cd2c09f15be..f6465f73a40ae 100644 --- a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.symbols @@ -27,30 +27,34 @@ interface J {} class C1 implements I<(x: T) => T> {} >C1 : Symbol(C1, Decl(heritage.ts, 4, 17)) >I : Symbol(I, Decl(heritage.ts, 2, 21)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 6, 23)) +>x : Symbol(x, Decl(heritage.ts, 6, 26)) +>T : Symbol(T, Decl(heritage.ts, 6, 23)) +>T : Symbol(T, Decl(heritage.ts, 6, 23)) class C2 extends B<(x: T) => T> {} >C2 : Symbol(C2, Decl(heritage.ts, 6, 40)) >B : Symbol(B, Decl(heritage.ts, 1, 31)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 7, 20)) +>x : Symbol(x, Decl(heritage.ts, 7, 23)) +>T : Symbol(T, Decl(heritage.ts, 7, 20)) +>T : Symbol(T, Decl(heritage.ts, 7, 20)) const C3 = class extends g()<(x: T) => T> {}; >C3 : Symbol(C3, Decl(heritage.ts, 8, 5)) >g : Symbol(g, Decl(heritage.ts, 0, 32)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 8, 30)) +>x : Symbol(x, Decl(heritage.ts, 8, 33)) +>T : Symbol(T, Decl(heritage.ts, 8, 30)) +>T : Symbol(T, Decl(heritage.ts, 8, 30)) interface I2 extends J<(x: T) => T> {} >I2 : Symbol(I2, Decl(heritage.ts, 8, 48)) >J : Symbol(J, Decl(heritage.ts, 3, 17)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(heritage.ts, 9, 24)) +>x : Symbol(x, Decl(heritage.ts, 9, 27)) +>T : Symbol(T, Decl(heritage.ts, 9, 24)) +>T : Symbol(T, Decl(heritage.ts, 9, 24)) type A1 = typeof f<(x: T) => T>; >A1 : Symbol(A1, Decl(heritage.ts, 9, 41)) @@ -137,17 +141,21 @@ declare function Comp

(props: { value: P }): JSX.Element; const j1 = (x: T) => T> value={f} />; >j1 : Symbol(j1, Decl(jsx.tsx, 8, 5)) >Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(jsx.tsx, 8, 23)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(jsx.tsx, 8, 18)) +>x : Symbol(x, Decl(jsx.tsx, 8, 21)) +>T : Symbol(T, Decl(jsx.tsx, 8, 18)) +>T : Symbol(T, Decl(jsx.tsx, 8, 18)) +>value : Symbol(value, Decl(jsx.tsx, 8, 32)) >f : Symbol(f, Decl(heritage.ts, 0, 13)) const j2 = (x: T) => T> value={f}>; >j2 : Symbol(j2, Decl(jsx.tsx, 9, 5)) >Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) ->T : Symbol(T, Decl(jsx.tsx, 9, 23)) ->T : Symbol(T, Decl(heritage.ts, 8, 35)) +>T : Symbol(T, Decl(jsx.tsx, 9, 18)) +>x : Symbol(x, Decl(jsx.tsx, 9, 21)) +>T : Symbol(T, Decl(jsx.tsx, 9, 18)) +>T : Symbol(T, Decl(jsx.tsx, 9, 18)) +>value : Symbol(value, Decl(jsx.tsx, 9, 32)) >f : Symbol(f, Decl(heritage.ts, 0, 13)) >Comp : Symbol(Comp, Decl(jsx.tsx, 5, 1)) diff --git a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types index 56fc59f25f60c..8e3baba18a6cd 100644 --- a/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types +++ b/tsc/testdata/baselines/reference/compiler/parseGenericArrowRatherThanLeftShift2.types @@ -17,63 +17,26 @@ interface J {} class C1 implements I<(x: T) => T> {} >C1 : C1 -><(x : boolean ->< : any ->T : any ->(x : any ->x : any ->T : any ->T> {} : boolean ->T : any ->{} : {} +>x : T class C2 extends B<(x: T) => T> {} >C2 : C2 ->B : typeof B -><(x : boolean ->< : any ->T : any ->(x : any ->x : any ->T : any ->T> {} : boolean ->T : any ->{} : {} +>B : B<(x: T) => T> +>x : T const C3 = class extends g()<(x: T) => T> {}; ->C3 : boolean ->class extends g()<(x : boolean ->class extends g()<class extends g() : typeof (Anonymous class) ->g() : typeof B +>C3 : typeof C3 +>class extends g()<(x: T) => T> {} : typeof C3 +>g() : B<(x: T) => T> >g : () => typeof B ->T : any ->(x : any ->x : any ->T : any ->T> {} : boolean ->T : any ->{} : {} +>x : T interface I2 extends J<(x: T) => T> {} -><(x : boolean ->< : any ->T : any ->(x : any ->x : any ->T : any ->T> {} : boolean ->T : any ->{} : {} +>x : T type A1 = typeof f<(x: T) => T>; ->A1 : (x: T) => T +>A1 : typeof f<(x: T) => T> >f : (x: T) => T -><(x: T) => T> : any -> : any >x : T const e1 = f<(x: T) => T>; @@ -150,41 +113,21 @@ declare function Comp

(props: { value: P }): JSX.Element; >JSX : any const j1 = (x: T) => T> value={f} />; ->j1 : boolean ->(x : boolean ->j1 : JSX.Element +>(x: T) => T> value={f} /> : JSX.Element >Comp :

(props: { value: P; }) => JSX.Element ->T : any ->(x : any ->x : any ->T : any ->T> value : boolean ->T : any ->value : any +>x : T +>value : (x: T) => T >f : (x: T) => T ->/> : RegExp const j2 = (x: T) => T> value={f}>; ->j2 : boolean ->(x : boolean ->j2 : JSX.Element +>(x: T) => T> value={f}> : JSX.Element >Comp :

(props: { value: P; }) => JSX.Element ->T : any ->(x : any ->x : any ->T : any ->T> value : boolean ->T : any ->value : any +>x : T +>value : (x: T) => T >f : (x: T) => T ->> : boolean -> : any -> : any ->Comp> : boolean >Comp :

(props: { value: P; }) => JSX.Element -> : any const j3 =

; >j3 : JSX.Element From 65e2afc57b6e9513ceec266116b2156e590114cf Mon Sep 17 00:00:00 2001 From: ahmad65saad Date: Sat, 10 Oct 2026 06:55:35 +0300 Subject: [PATCH 3/3] Add JSDoc @augments/@implements case with a generic function type argument --- ...nts_genericFunctionTypeArgument.errors.txt | 25 ++++++++++ ...gments_genericFunctionTypeArgument.symbols | 46 +++++++++++++++++++ ...Augments_genericFunctionTypeArgument.types | 43 +++++++++++++++++ ...docAugments_genericFunctionTypeArgument.ts | 26 +++++++++++ 4 files changed, 140 insertions(+) create mode 100644 tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.errors.txt create mode 100644 tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.symbols create mode 100644 tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.types create mode 100644 tsc/testdata/tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts diff --git a/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.errors.txt b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.errors.txt new file mode 100644 index 0000000000000..d5523f6651b78 --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.errors.txt @@ -0,0 +1,25 @@ +/b.js(1,15): error TS8023: JSDoc '@augments A' does not match the 'extends A' clause. + + +==== /a.d.ts (0 errors) ==== + declare class A { x: T } + interface I { y: T } + +==== /b.js (1 errors) ==== + /** @augments A<(x: T) => T> */ + ~ +!!! error TS8023: JSDoc '@augments A' does not match the 'extends A' clause. + class B extends A { + m() { + return this.x; + } + } + + /** @implements {I<(x: T) => T>} */ + class C { + constructor() { + /** @type {(x: T) => T} */ + this.y = x => x; + } + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.symbols b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.symbols new file mode 100644 index 0000000000000..b494c063384ea --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts] //// + +=== /a.d.ts === +declare class A { x: T } +>A : Symbol(A, Decl(a.d.ts, 0, 0)) +>T : Symbol(T, Decl(a.d.ts, 0, 16)) +>x : Symbol(A.x, Decl(a.d.ts, 0, 20)) +>T : Symbol(T, Decl(a.d.ts, 0, 16)) + +interface I { y: T } +>I : Symbol(I, Decl(a.d.ts, 0, 27)) +>T : Symbol(T, Decl(a.d.ts, 1, 12)) +>y : Symbol(I.y, Decl(a.d.ts, 1, 16)) +>T : Symbol(T, Decl(a.d.ts, 1, 12)) + +=== /b.js === +/** @augments A<(x: T) => T> */ +class B extends A { +>B : Symbol(B, Decl(b.js, 0, 0)) +>A : Symbol(A, Decl(a.d.ts, 0, 0)) + + m() { +>m : Symbol(B.m, Decl(b.js, 1, 19)) + + return this.x; +>this.x : Symbol(A.x, Decl(a.d.ts, 0, 20)) +>this : Symbol(B, Decl(b.js, 0, 0)) +>x : Symbol(A.x, Decl(a.d.ts, 0, 20)) + } +} + +/** @implements {I<(x: T) => T>} */ +class C { +>C : Symbol(C, Decl(b.js, 5, 1)) + + constructor() { + /** @type {(x: T) => T} */ + this.y = x => x; +>this.y : Symbol(C.y, Decl(b.js, 9, 19)) +>this : Symbol(C, Decl(b.js, 5, 1)) +>y : Symbol(C.y, Decl(b.js, 9, 19)) +>x : Symbol(x, Decl(b.js, 11, 16)) +>x : Symbol(x, Decl(b.js, 11, 16)) + } +} + diff --git a/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.types b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.types new file mode 100644 index 0000000000000..1b4d5ee29eec2 --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/jsdocAugments_genericFunctionTypeArgument.types @@ -0,0 +1,43 @@ +//// [tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts] //// + +=== /a.d.ts === +declare class A { x: T } +>A : A +>x : T + +interface I { y: T } +>y : T + +=== /b.js === +/** @augments A<(x: T) => T> */ +class B extends A { +>B : B +>A : A<(x: T) => T> + + m() { +>m : () => (x: T) => T + + return this.x; +>this.x : (x: T) => T +>this : this +>x : (x: T) => T + } +} + +/** @implements {I<(x: T) => T>} */ +class C { +>C : C + + constructor() { + /** @type {(x: T) => T} */ + this.y = x => x; +>this.y = x => x : (x: T) => T +>this.y : (x: T) => T +>this : this +>y : (x: T) => T +>x => x : (x: T) => T +>x : T +>x : T + } +} + diff --git a/tsc/testdata/tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts b/tsc/testdata/tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts new file mode 100644 index 0000000000000..ffdcda0fbd425 --- /dev/null +++ b/tsc/testdata/tests/cases/conformance/jsdoc/jsdocAugments_genericFunctionTypeArgument.ts @@ -0,0 +1,26 @@ +// @target: es2015 +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/47410 + +// @Filename: /a.d.ts +declare class A { x: T } +interface I { y: T } + +// @Filename: /b.js +/** @augments A<(x: T) => T> */ +class B extends A { + m() { + return this.x; + } +} + +/** @implements {I<(x: T) => T>} */ +class C { + constructor() { + /** @type {(x: T) => T} */ + this.y = x => x; + } +}