Fix ThisParameterType<T> type (#36013)

* Simplify ThisParameterType<T> type

* Add tests
This commit is contained in:
Anders Hejlsberg 2020-01-06 08:55:34 -10:00 committed by GitHub
parent 28319a541a
commit df3b5bbdab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 1 deletions

2
src/lib/es5.d.ts vendored
View file

@ -298,7 +298,7 @@ declare var Function: FunctionConstructor;
/**
* Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.
*/
type ThisParameterType<T> = T extends (this: unknown, ...args: any[]) => any ? unknown : T extends (this: infer U, ...args: any[]) => any ? U : unknown;
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
/**
* Removes the 'this' parameter from a function type.

View file

@ -0,0 +1,16 @@
//// [strictBindCallApply2.ts]
// Repro from #32964
interface Foo { blub: string };
function fn(this: Foo) {}
type Test = ThisParameterType<typeof fn>;
const fb = fn.bind({ blub: "blub" });
//// [strictBindCallApply2.js]
// Repro from #32964
;
function fn() { }
var fb = fn.bind({ blub: "blub" });

View file

@ -0,0 +1,24 @@
=== tests/cases/conformance/functions/strictBindCallApply2.ts ===
// Repro from #32964
interface Foo { blub: string };
>Foo : Symbol(Foo, Decl(strictBindCallApply2.ts, 0, 0))
>blub : Symbol(Foo.blub, Decl(strictBindCallApply2.ts, 2, 15))
function fn(this: Foo) {}
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
>this : Symbol(this, Decl(strictBindCallApply2.ts, 3, 12))
>Foo : Symbol(Foo, Decl(strictBindCallApply2.ts, 0, 0))
type Test = ThisParameterType<typeof fn>;
>Test : Symbol(Test, Decl(strictBindCallApply2.ts, 3, 25))
>ThisParameterType : Symbol(ThisParameterType, Decl(lib.es5.d.ts, --, --))
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
const fb = fn.bind({ blub: "blub" });
>fb : Symbol(fb, Decl(strictBindCallApply2.ts, 7, 5))
>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)
>fn : Symbol(fn, Decl(strictBindCallApply2.ts, 2, 31))
>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)
>blub : Symbol(blub, Decl(strictBindCallApply2.ts, 7, 20))

View file

@ -0,0 +1,24 @@
=== tests/cases/conformance/functions/strictBindCallApply2.ts ===
// Repro from #32964
interface Foo { blub: string };
>blub : string
function fn(this: Foo) {}
>fn : (this: Foo) => void
>this : Foo
type Test = ThisParameterType<typeof fn>;
>Test : Foo
>fn : (this: Foo) => void
const fb = fn.bind({ blub: "blub" });
>fb : () => void
>fn.bind({ blub: "blub" }) : () => void
>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; }
>fn : (this: Foo) => void
>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; }
>{ blub: "blub" } : { blub: string; }
>blub : string
>"blub" : "blub"

View file

@ -0,0 +1,11 @@
// @strictFunctionTypes: false
// @strictBindCallApply: true
// Repro from #32964
interface Foo { blub: string };
function fn(this: Foo) {}
type Test = ThisParameterType<typeof fn>;
const fb = fn.bind({ blub: "blub" });