Closed
Description
TypeScript Version: 2.8.0-dev.20180131
Search Terms: callback type inference, incorrect overload
Code
interface TestFunction {
<T>(input: { [key: number]: T }, callback: (value: T, key: number, collection: { [key: number]: T }) => boolean): boolean;
<T extends object>(input: T, callback: (value: T[keyof T], key: string, collection: T) => boolean): boolean;
}
const fn: TestFunction = {} as any;
fn({ a: "a", b: "b" }, (value, key) => true);
Expected behavior: Code should compile successfully
Actual behavior: Compile error:
src\test.ts (10,32): Argument of type '(value: {}, key: number) => boolean' is not assignable to parameter of type '(value: string, key: string, collection: { a: string; b: string; c: string; }) => boolean'.
Types of parameters 'key' and 'key' are incompatible.
Type 'string' is not assignable to type 'number'. (2345)
Related Issues: DefinitelyTyped/DefinitelyTyped#23317
Notes:
- The code above works in typescript 2.4. It seems to have broken in 2.5 and later (including 2.8).
- It appears as if it's inferring the callback type based on the first overload, then failing to match it to the second overload.
- The generic types seem necessary to reproduce the issue. I tried removing them and the issue went away.
- If I explicitly pass the generic type argument, the code compiles successfully, i.e:
fn<{ a: "a", b: "b" }>({ a: "a", b: "b" }, (value, key) => true);
- If I remove the second callback parameter, the code compiles successfully, i.e:
fn({ a: "a", b: "b" }, (value) => true);
- Enabling/disabling
strictFunctionTypes
does not affect the result