-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
π Search Terms
function parameter display signature helper inconsistent union
π Version & Regression Information
This is the behavior in every version I tried
β― Playground Link
π» Code
declare const optionals:
| ((a?: { a: true }) => unknown)
| ((b?: { b: true }) => unknown)
declare const optionalDisplay: (
arg0: ({ a: true } & { b: true }) | undefined
) => unknown
// This signature errors when not passed an arg
optionalDisplay()
// Display signature (incorrect)
// optionals(arg0: ({ a: true; } & { b: true; }) | undefined): unknown
// Behavior (correct)
// optionals(arg0?: ({ a: true; } & { b: true; }): unknown
optionals()
declare const rest:
| ((a?: { a: true }, ...rest: string[]) => unknown)
| ((b?: { b: true }) => unknown)
// Display signature (incorrect, notice rest is not actually a rest element)
// (arg0: ({ a: true;} & { b: true; }) | undefined, rest: string[]) => unkonwn
// Behavior (correct)
// (arg0?: ({ a: true;} & { b: true; }), ...rest: string[]) => unkonwn
rest({ a: true, b: true }, "foo", "bar")π Actual behavior
Types are enforced correctly but displayed incorrectly
π Expected behavior
The actual types enforced should be the same as those displayed.
Additional information about the issue
There are likely many other scenarios where these inconsistencies occur (and there may be cases where the behavior is also incorrect). I was recently working on a utility that required providing parameters to a union of function types like this, and ended up writing a custom intersectParameters generic. I believe this correctly handles all edge cases involving variadic and optional elements (the results for non-trailing variadic elements are suboptimal but I believe that is a result of how TS handles them in general).
This could potentially be useful in adapting a runtime solution to ensure these signatures are displayed correctly, e.g.:
I also made a version that was parameterized to handle reducing tuple intersections as well since it's a very related problem- happy to share that if it would be useful.
It would be great if robust logic for these kinds of operations were made available through TS directly in situations like this so that I could avoid maintaining these types going forward!
