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

Enable Inferring from Overloaded Functions #60836

Open
6 tasks done
LukeAbby opened this issue Dec 21, 2024 · 1 comment
Open
6 tasks done

Enable Inferring from Overloaded Functions #60836

LukeAbby opened this issue Dec 21, 2024 · 1 comment

Comments

@LukeAbby
Copy link

πŸ” Search Terms

inferring, function overload

βœ… Viability Checklist

⭐ Suggestion

Make it possible to infer an overloaded function when trying to assign to one. This would make it more convenient to reuse overloaded functions.

When the function has explicitly typed inputs and outputs it would be able to reuse the same logic that's used to check if an implementation signature of an overloaded function is compatible with its overload signatures. When an argument or return type needs to be inferred then a union of all possible values is probably what should be inferred. This is already partially implemented.

This proposal is complimentary to other proposals like #59350 or #54539 but it's intentionally more limited in scope to some others. I'm aware of the overlap but I see this as a separate proposal because it's a fix for specifically the inference side of things, rather than anything more broad.

πŸ“ƒ Motivating Example

Currently this is what happens when you try:

interface SomeLongOverload {
    (x: string): string;
    (y: number | number[]): number[];
    (z: string[]): string;
    (a: number, b?: number): [number, number];
}

declare class BaseClass {
    someLongOverload1: SomeLongOverload;
    someLongOverload2: SomeLongOverload;
}

class SubClass extends BaseClass {
    someLongOverload1: SomeLongOverload = (a) => { ... }
    //              ^                      ^ This infers correctly as `string | number | number[] | string[] | number`
    //              ^
    //              ^ Type '(a: string | number | number[] | string[]) => string | number[] | string | [number, number]' is not assignable to type 'SomeLongOverload'.
    //                  Type 'string | number[] | [number, number]' is not assignable to type 'string'.
    //                    Type 'number[]' is not assignable to type 'string'.

    someLongOverload2: SomeLongOverload = (a, b) => { ... }
    //              ^                      ^  ^ infers as `number | undefined`
    //              ^                      ^
    //              ^                      ^ infers as `number`
    //              ^
    //              ^ Type '(a: number, b: number | undefined) => string | number[] | string | [number, number]' is not assignable to type 'SomeLongOverload'.
    //                  Target signature provides too few arguments. Expected 2 or more, but got 1.
}

Playground

Ideally neither of these examples would error and the second example would infer correctly. It seems that the current way inference works is to extract the types from all overloads with the same arity or greater. Given the nature of function overloads this should probably be changed.

If there are concerns with automatically inferring overloads in the general case, e.g. for something like takesLongOverloadedFunction((a, b) => { ... }) then it could be limited to cases of the form const x: SomeLongOverload = (...) => ...;. I can understand arguments both directions for takesLongOverloadedFunction because it could easily mask obvious errors.

πŸ’» Use Cases

  1. What do you want to use this for? Being more DRY
  2. What shortcomings exist with current approaches? Duplication of code. Increased difficulty to refactor.
  3. What workarounds are you using in the meantime? Being much more verbose.
@LukeAbby LukeAbby changed the title Enable Inferring Function Overloads Enable Inferring from Overloaded Functions Dec 21, 2024
@MartinJohns
Copy link
Contributor

Duplicate of #47669.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants