Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function overload breaks generics #29312

Closed
OliverJAsh opened this issue Jan 8, 2019 · 4 comments
Closed

Function overload breaks generics #29312

OliverJAsh opened this issue Jan 8, 2019 · 4 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@OliverJAsh
Copy link
Contributor

TypeScript Version: 3.1.6

Search Terms: overload function generic

Code

declare function identity <T extends unknown>(t: T): T
declare function identity (): undefined

declare class Option<A> {
  chain<B>(f: (a: A) => Option<B>): Option<B>;
}

// Actual type: <T>(option: Option<Option<T>>) => Option<{}>
// Expected type: <T>(option: Option<Option<T>>) => Option<T>
// Disabling second `identity` overload fixes it for some reason.
const optionFlatten = <T>(option: Option<Option<T>>) => option.chain(identity)
@wKich
Copy link

wKich commented Jan 9, 2019

I have same issue in another example (TypeScript version: 3.2.2)

function foo(a: number, b: string): void;
function foo(a: string): void;

function foo(a: string | number, b?: string) {}

foo.call(null, 1, "2"); // Expected 2 arguments, but got 3.
foo.bind(null)(1, "2"); // Expected 1 arguments, but got 2.
foo.apply(null, [1, "2"]); // Type 'number' is not assignable to type 'string'.

foo.call(null, "2"); // no errors
foo(1, "2"); // no errors
foo("2"); // no errors

So I can't use call/bind/apply with overloaded functions.

Update: Sorry, I didn't see #27028 (comment)

@weswigham weswigham added the Needs Investigation This issue needs a team member to investigate its status. label Jan 10, 2019
@Bludator
Copy link

Bludator commented Mar 3, 2019

I have yet another example:

function Wrap<O extends (...any) => any>(a: O, params: Parameters<O>): void { }

let Bar: {
    Foo<K extends "FooBar">(a: K, b: number): void;
    //comment out this ↓ line:
    Foo(a: never): never;
};

//This should work:
Wrap(Bar.Foo, ["FooBar", 78])

link to playground.

@jack-williams
Copy link
Collaborator

@Bludator That is a separate issue linked to the design of conditional type inference. When inferring from an overloaded function the last overload is always picked, so Parameters just picks up the last case which happens to be never.

See #21496

@RyanCavanaugh RyanCavanaugh added Design Limitation Constraints of the existing architecture prevent this from being fixed and removed Needs Investigation This issue needs a team member to investigate its status. labels Jul 23, 2019
@RyanCavanaugh
Copy link
Member

Inference only works with the last overload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

6 participants