You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bring the behavior when calling "pseudo-overloaded" functions (functions whose rest parameter is of a union of tuple types) in line with the behavior when calling "true overloaded" functions.
π Motivating Example
When you call a true overloaded function, the compiler will, for example, contextually type a callback parameter based on the resolved call signature:
Whereas the "pseudo-overloaded" version of this (which IntelliSense presents as overloads as of #38234), the compiler is not able to do such contextual typing:
It would be nice (although I understand that it might not be easily done) if callers could treat pseudo-overloads as true overloads, or at least more like true overloads.
π» Use Cases
None of these are show-stoppers, btw
allow refactoring of overloads/generics to pseudo-overloads without affecting callers
In situations where the return type of a function does not depend on the parameter types, you can get some better behavior inside a function implementation with a pseudo-overload instead of either a generic that extends a union (see #13995) or a true overload (#18533):
functiongen<Kextends"s"|"n">(type: K,val: {s: string,n: number}[K]): string{return(type==="s") ? val.toUpperCase() : val.toFixed();// error! can't narrow K this way}functionovl(type: "s",val: string): string;functionovl(type: "n",val: number): string;functionovl(type: "s"|"n",val: string|number){return(type==="s") ? val.toUpperCase() : val.toFixed();// error! type and val are uncorrelated }functionpseudo(...args: [type: "s",val: string]|[type: "n",val: number]): string{const[type,val]=args;(type==="s") ? val.toUpperCase() : val.toFixed();// error, type and val are still uncorrelated, #30581return(args[0]==="s") ? args[1].toUpperCase() : args[1].toFixed();// but this works!}
I'm not thrilled about not being able to destructure args before the check of args[0], but at least it's possible to get some discriminated union type checking in the implementation. From the caller's side, though, it would be nice if I didn't have to worry about the difference between ovl()'s and pseudo()'s call signatures. And since IntelliSense presents them as overloads in some situations, it can lead to confusion when two "same" functions behave differently at call sites.
programmatic generation of overloaded function call signatures:
If pseudo-overloads behaved more like overloads from the caller side, I'd have no reservations suggesting something like this:
Related issues: #31977: better intellisense for discriminated union tuples #38234: treat functions with unions of rest tuples as a rest argument as "pseudo-overloads"
The text was updated successfully, but these errors were encountered:
I'm still trying to wrap my head around what it would take to make it work today. There might be some implementation overlap with https://github.com/microsoft/TypeScript/pull/52944/files to be found here but I'm not sure yet. There is code there that explores alternative inferences, fork inference contexts, etc and those things seem to be related to the suggestion here. It would be great if a union member that can't be matched would not impact the inference anyhow and if it would get discarded altogether from the possible "candidates". On the other hand, with true overloads, only one can be matched and those pseudo overloads can today (likely) match multiple alternatives and that might have to be retained.
Suggestion
π Search Terms
rest tuple, union, overloads, contextual typing
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
Bring the behavior when calling "pseudo-overloaded" functions (functions whose rest parameter is of a union of tuple types) in line with the behavior when calling "true overloaded" functions.
π Motivating Example
When you call a true overloaded function, the compiler will, for example, contextually type a callback parameter based on the resolved call signature:
Whereas the "pseudo-overloaded" version of this (which IntelliSense presents as overloads as of #38234), the compiler is not able to do such contextual typing:
It would be nice (although I understand that it might not be easily done) if callers could treat pseudo-overloads as true overloads, or at least more like true overloads.
π» Use Cases
None of these are show-stoppers, btw
allow refactoring of overloads/generics to pseudo-overloads without affecting callers
In situations where the return type of a function does not depend on the parameter types, you can get some better behavior inside a function implementation with a pseudo-overload instead of either a generic that extends a union (see #13995) or a true overload (#18533):
I'm not thrilled about not being able to destructure
args
before the check ofargs[0]
, but at least it's possible to get some discriminated union type checking in the implementation. From the caller's side, though, it would be nice if I didn't have to worry about the difference betweenovl()
's andpseudo()
's call signatures. And since IntelliSense presents them as overloads in some situations, it can lead to confusion when two "same" functions behave differently at call sites.programmatic generation of overloaded function call signatures:
If pseudo-overloads behaved more like overloads from the caller side, I'd have no reservations suggesting something like this:
Otherwise, I need to do something union-to-intersection-like the following:
which is fun but ugly.
Playground link
Related issues:
#31977: better intellisense for discriminated union tuples
#38234: treat functions with unions of rest tuples as a rest argument as "pseudo-overloads"
The text was updated successfully, but these errors were encountered: