Skip to content

Commit df3b5bb

Browse files
authored
Fix ThisParameterType<T> type (microsoft#36013)
* Simplify ThisParameterType<T> type * Add tests
1 parent 28319a5 commit df3b5bb

File tree

5 files changed

+76
-1
lines changed

5 files changed

+76
-1
lines changed

src/lib/es5.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ declare var Function: FunctionConstructor;
298298
/**
299299
* Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.
300300
*/
301-
type ThisParameterType<T> = T extends (this: unknown, ...args: any[]) => any ? unknown : T extends (this: infer U, ...args: any[]) => any ? U : unknown;
301+
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
302302

303303
/**
304304
* Removes the 'this' parameter from a function type.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [strictBindCallApply2.ts]
2+
// Repro from #32964
3+
4+
interface Foo { blub: string };
5+
function fn(this: Foo) {}
6+
7+
type Test = ThisParameterType<typeof fn>;
8+
9+
const fb = fn.bind({ blub: "blub" });
10+
11+
12+
//// [strictBindCallApply2.js]
13+
// Repro from #32964
14+
;
15+
function fn() { }
16+
var fb = fn.bind({ blub: "blub" });
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/functions/strictBindCallApply2.ts ===
2+
// Repro from #32964
3+
4+
interface Foo { blub: string };
5+
>Foo : Symbol(Foo, Decl(strictBindCallApply2.ts, 0, 0))
6+
>blub : Symbol(Foo.blub, Decl(strictBindCallApply2.ts, 2, 15))
7+
8+
function fn(this: Foo) {}
9+
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
10+
>this : Symbol(this, Decl(strictBindCallApply2.ts, 3, 12))
11+
>Foo : Symbol(Foo, Decl(strictBindCallApply2.ts, 0, 0))
12+
13+
type Test = ThisParameterType<typeof fn>;
14+
>Test : Symbol(Test, Decl(strictBindCallApply2.ts, 3, 25))
15+
>ThisParameterType : Symbol(ThisParameterType, Decl(lib.es5.d.ts, --, --))
16+
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
17+
18+
const fb = fn.bind({ blub: "blub" });
19+
>fb : Symbol(fb, Decl(strictBindCallApply2.ts, 7, 5))
20+
>fn.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
21+
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
22+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
23+
>blub : Symbol(blub, Decl(strictBindCallApply2.ts, 7, 20))
24+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/functions/strictBindCallApply2.ts ===
2+
// Repro from #32964
3+
4+
interface Foo { blub: string };
5+
>blub : string
6+
7+
function fn(this: Foo) {}
8+
>fn : (this: Foo) => void
9+
>this : Foo
10+
11+
type Test = ThisParameterType<typeof fn>;
12+
>Test : Foo
13+
>fn : (this: Foo) => void
14+
15+
const fb = fn.bind({ blub: "blub" });
16+
>fb : () => void
17+
>fn.bind({ blub: "blub" }) : () => void
18+
>fn.bind : { <T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>; <T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R; <T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R; <T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R; <T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R; <T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R; }
19+
>fn : (this: Foo) => void
20+
>bind : { <T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>; <T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R; <T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R; <T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R; <T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R; <T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R; }
21+
>{ blub: "blub" } : { blub: string; }
22+
>blub : string
23+
>"blub" : "blub"
24+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @strictFunctionTypes: false
2+
// @strictBindCallApply: true
3+
4+
// Repro from #32964
5+
6+
interface Foo { blub: string };
7+
function fn(this: Foo) {}
8+
9+
type Test = ThisParameterType<typeof fn>;
10+
11+
const fb = fn.bind({ blub: "blub" });

0 commit comments

Comments
 (0)