Typescript: Function overload do not pick up right case

Created on 15 Nov 2017  路  3Comments  路  Source: microsoft/TypeScript




TypeScript Version: 2.7.0-dev.201xxxxx

Example 1

Code

interface Dict<T> {
  [key: string]: T
}

declare function filter<T>(fn: (value: T) =>聽boolean): (x: Dict<T>) => Dict<T>;
declare function filter<T>(fn: (value: T) =>聽boolean): (x: T[]) => T[];

declare function pipe<V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1;
declare function pipe<V0, T1, T2>(fn0: (x0: V0) => T1, fn1: (x: T1) => T2): (x0: V0) => T2;

const x = pipe(filter((x: string) => true))

console.log(x(['foo']))

Expected behavior:

x is of type (v: string[]) => string[]

Actual behavior:

Argument of type 'string[]' is not assignable to parameter of type 'Dict'.

Example 2

Code

interface Dict<T> {
  [key: string]: T
}

declare function filter<T>(fn: (value: T) =>聽boolean): (x: Dict<T>) => Dict<T>;
declare function filter<T>(fn: (value: T) =>聽boolean): (x: T[]) => T[];

declare function pipe<V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1;
declare function pipe<V0, T1, T2>(fn0: (x0: V0) => T1, fn1: (x: T1) => T2): (x0: V0) => T2;

// >>> specialized id, which should specify filter overload
const id = (x: string[]): string[] => x

const x = pipe(id, filter((x: string) => true))

console.log(x(['foo']))

Expected behavior:

x is of type (v: string[]) => string[]

Actual behavior:

Argument of type 'string[]' is not assignable to parameter of type 'Dict'. Now failing on filter.

Working as Intended

Most helpful comment

Your call to filter undergoes overload resolution based on its arguments, not on the type it will eventually flow into.

It doesn't really make sense in our type system for filter to have two overloads with identical parameter lists. What you probably want is for filter to return something which itself has overloads:

declare function filter(fn: (value: T) => boolean): {
(x: Dict): Dict;
(x: T[]): T[];
}

All 3 comments

Your call to filter undergoes overload resolution based on its arguments, not on the type it will eventually flow into.

It doesn't really make sense in our type system for filter to have two overloads with identical parameter lists. What you probably want is for filter to return something which itself has overloads:

declare function filter(fn: (value: T) => boolean): {
(x: Dict): Dict;
(x: T[]): T[];
}

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

That does not work either. However, thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antony-Jones picture Antony-Jones  路  3Comments

bgrieder picture bgrieder  路  3Comments

jbondc picture jbondc  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments

blendsdk picture blendsdk  路  3Comments