Skip to content

"...args: infer" on an overloaded function chooses only one function head #26136

Closed
@mike-north

Description

@mike-north

TypeScript Version: 3.1.0-dev.20180801

Search Terms: overload, infer, function heads, tuple, rest parameter

Code

interface Foo {
  (a: string, b: number, c: boolean): void;
  (a: number, b: string, c: boolean): void;
}

type Args<F> = F extends (...args: infer T) => any ? T : never;

let x: Args<Foo> = [42, 'hello world', true]; // ✅
x = ['hello world', 42, true]; // 💥

Expected behavior:
Ideally, I would hope for the typeof x to be

let x: [string, number, boolean] | [number, string, boolean]

although not entirely correct, I would even take a type wide enough to accomodate both function heads.

let x: [string|number, number|string, boolean]

Actual behavior:
The type of x ends up being

let x: [number, string, boolean]

Playground Link: https://www.typescriptlang.org/play/#src=interface%20Foo%20%7B%0D%0A%20%20(a%3A%20string%2C%20b%3A%20number%2C%20c%3A%20boolean)%3A%20void%3B%0D%0A%20%20(a%3A%20number%2C%20b%3A%20string%2C%20c%3A%20boolean)%3A%20void%3B%0D%0A%7D%0D%0A%0D%0Atype%20Args%3CF%3E%20%3D%20F%20extends%20(...args%3A%20infer%20T)%20%3D%3E%20any%20%3F%20T%20%3A%20never%3B%0D%0A%0D%0Alet%20x%3A%20Args%3CFoo%3E%20%3D%20%5B42%2C%20'hello%20world'%2C%20true%5D%3B%20%2F%2F%20%E2%9C%85%0D%0Ax%20%3D%20%5B'hello%20world'%2C%2042%2C%20true%5D%3B%20%2F%2F%20%F0%9F%92%A5

Related Issues: #24897, #5453 (maybe)

Metadata

Metadata

Assignees

No one assigned

    Labels

    SuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions