Open
Description
TypeScript Version: 3.6.3
Search Terms:
call, bind, apply, function, functions, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, union, return, this, strictBindCallApply
Code
type aFn = (this: string, value: string) => string;
type bFn = (this: string, value: string) => Promise<string>;
function callFn(callback: aFn | bFn): Promise<string> | string {
return callback.call("hello", "world");
}
function applyFn(callback: aFn | bFn): Promise<string> | string {
return callback.apply("hello", ["world"]);
}
function bindFn(callback: aFn | bFn): () => Promise<string> | string {
return callback.bind("hello", "world");
}
Expected behavior:
Code compiles. The types in this code are equivalent to the types in the following example, which does compile:
type cFn = (this: string, value: string) => string | Promise<string>;
function callFn1(callback: cFn): Promise<string> | string {
return callback.call("hello", "world");
}
function applyFn1(callback: cFn): Promise<string> | string {
return callback.apply("hello", ["world"]);
}
function bindFn1(callback: cFn): () => Promise<string> | string {
return callback.bind("hello", "world");
}
The only difference between the two examples is that the first uses a type union of function types aFn
and bFn
, which only differ in terms of return value, whereas the second uses a type union in the return value of cFn
. In other words I think the union of type aFn
and bFn
should behave the same as type cFn
.
type aFn = (this: string, value: string) => string;
type bFn = (this: string, value: string) => Promise<string>;
type cFn = (this: string, value: string) => string | Promise<string>;
Actual behavior:
example.ts(5,12): error TS2684: The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", args_0: string) => string'.
Type 'bFn' is not assignable to type '(this: "hello", args_0: string) => string'.
Type 'Promise<string>' is not assignable to type 'string'.
example.ts(9,12): error TS2684: The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", value: string) => string'.
Type 'bFn' is not assignable to type '(this: "hello", value: string) => string'.
Type 'Promise<string>' is not assignable to type 'string'.
example.ts(13,12): error TS2769: No overload matches this call.
Overload 1 of 6, '(this: (this: "hello", arg0: "world") => string, thisArg: "hello", arg0: "world"): () => string', gave the following error.
The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", arg0: "world") => string'.
Type 'bFn' is not assignable to type '(this: "hello", arg0: "world") => string'.
Type 'Promise<string>' is not assignable to type 'string'.
Overload 2 of 6, '(this: (this: "hello", ...args: "world"[]) => string, thisArg: "hello", ...args: "world"[]): (...args: "world"[]) => string', gave the following error.
The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", ...args: "world"[]) => string'.
Type 'bFn' is not assignable to type '(this: "hello", ...args: "world"[]) => string'.
Type 'Promise<string>' is not assignable to type 'string'.
Related Issues: