-
Notifications
You must be signed in to change notification settings - Fork 12.8k
An overloaded function cannot call identical overloaded function with its parameters #53318
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
Comments
Ok, thanks. I never came across this in 3 years of using TS and I have been using plenty overloads. It's good to know that, better late then never but I wished the docs mentioned it. This is an issue that will not come up immediately, so there may be plenty of code using overloads that will need to be refactored upon realization that there is a major bug that has been marked as wontfix. I only found: "Always prefer parameters with union types instead of overloads when possible" but I don't think it sufficiently warns against it. I would interpret it as "use union types if you don't need to narrow the return type based on the input arg". And when I try to implement the same with a conditional type in the return, I find myself between the rock and a hard place. I run into a bug I encountered earlier #52051 . As a matter of fact, my workaround to that bug was using overloads :) Edit: It seems to be possible to override it with casting after all. function get<Arg extends string | string[] | undefined>(
idOrIds: Arg
) : Arg extends string ? string | null
: Arg extends string[] ? Record<string, string | null>
: Record<string, string> {
if (typeof idOrIds === 'string') {
return ''; // Not assignable
}
}
function get2<Arg extends string | string[] | undefined>(
idOrIds: Arg
) : Arg extends string ? string | null
: Arg extends string[] ? Record<string, string | null>
: Record<string, string> {
if (typeof idOrIds === 'string') {
return '' as ReturnType<typeof get2<Arg>>; // Ok
}
} Edit2: Hmm, actually I cannot get the above function to work properly when the argument is not supplied. I will investigate it further and update this if anything applies to the current bug. Edit3: It's possible to use a combo of overload to deal with the missing parameter and conditional types to deal with the union bug. function get3(): Record<string, string>;
function get3<Arg extends string | string[] | undefined>(
idOrIds?: Arg
) : Arg extends string ? string | null
: Arg extends string[] ? Record<string, string | null>
: Arg extends undefined ? Record<string, string> : never;
function get3(idsOrId?: string | string[]): string | null | Record<string, string | null> | Record<string, string>
{
if (typeof idsOrId === 'string') {
return '';
}
}
let a = get3('');
let b = get3([]);
let c = get3(undefined);
let d = get3();
function get4(): Record<string, string>;
function get4<Arg extends string | string[] | undefined>(
idOrIds?: Arg
) : Arg extends string ? string | null
: Arg extends string[] ? Record<string, string | null>
: Arg extends undefined ? Record<string, string> : never;
function get4(idsOrId?: string | string[]): string | null | Record<string, string | null> | Record<string, string> {
return get3(idsOrId);
} |
Bug Report
🔎 Search Terms
no overload matches call implementation succeed
🕗 Version & Regression Information
At least in 4.9 and it does occur in the current nightly
This is the behavior in every version I tried, and I reviewed the FAQ for entries.
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Trying to call a function with the same overloaded parameters will result in a "no overload matches this call" error.
🙂 Expected behavior
There should be no error. It's pretty clear that the types are compatible.
The text was updated successfully, but these errors were encountered: