microsoft / microsoft/TypeScript
bind, call and apply do not work on unions of function types with different return types.
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
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:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the union-of-function-types example in the linked TypeScript Playground, then compare it with the equivalent union-return-type example. Trace the handling of call, apply, and bind for unions in the compiler; done means all three examples compile with the expected return types.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100