Skip to content

Wrong callback type inferred with multiple overloads #21525

Closed
@aj-r

Description

@aj-r

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixedFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions