-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Parameter type narrowing should consider function overload signatures #14515
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
This is easy enough to reason about for two overloads but quickly gets out of hand for more complex scenarios. It's going to be very complex to produce a single data structure which succinctly defines the relationship between these parameters: function fn(x: string, y: number): void;
function fn(x: string, y: string: void;
function fn(x: number, y: number, z: string): void;
function fn(x: number | string, y: number | string, z?: string) {
// Quick, what checks produce what type guards?
} We also don't have any mechanism for "if x is T then y is U" inferences. |
Couldn't you use a simple graph for this? It'd have an entry node for each argument, with convergence where commonalities appear among overloads. You could use something like a suffix tree that wraps back in on itself. Radix trees also seem relevant, but are constrained by ordinality. Still, might be good inspiration for a versatile solution. |
This is two years late but, In some cases, you can get the kind of narrowing you want. |
Interestingly, a somewhat isomorphic example to #33704 already works as expected, so it might be possible to do something about this issue: type __foo_params =
| {a?: never, b?: never}
| {a: string, b: string}
function foo(__params: __foo_params): void {
if (!__params.a) return
console.log(__params.a.length + __params.b.length) // no error
} |
Uh oh!
There was an error while loading. Please reload this page.
TypeScript Version: 2.2.1
Code
The third (unified) function signature is hidden from the call site, and therefore any arguments should be able to be narrowed based on inspection of the provided arguments. In the case above, the second argument is only defined if the first argument is of type
A
, and so I would expect narrowing of the argument type to occur accordingly. One could make the argument that in the compiled output, it's possible for JavaScript to still pass subsequent arguments, but then why narrow types at all, seeing as JavaScript can always violate every type constraint that TypeScript makes inferences from?The text was updated successfully, but these errors were encountered: