-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Generic rest of intersection should be assignable to its type parameter constituents #28636
Comments
While this is desirable for spreads specifically, I don't think we'd want to do this for intersections in conditionals in general, as it'd start allowing a bunch of unsound conditional type assignments (not just the object rest one). I also don't think any simplification rules relying on the exact conditional or mapped type used ( |
How often are spread operations on objects like this used when constituents of the intersection are not disjoint? The disjoint case seems far more useful (to me). Would it be possible to have a strict spread mode where spreading a value of type EDIT: Disclaimer. I haven't really been following the generic spread stuff especially closely, so I apologise if I missed something obvious or previously covered. |
Real-world example: https://github.com/AlCalzone/ioBroker.tradfri/blob/master/src/main.ts#L548 const config: ioBroker.AdapterConfig = {
...adapter.config,
...newConfig,
}; where |
Search Terms
generic rest intersection type parameter
Suggestion
The rest of an intersection containing type parameters and object types should be assignable to the type parameters if the rest removed all the properties from the object types. For example:
This is technically not safe — the instantiation of the type parameters could overlap with the object types — but it is how higher-order spread currently behaves. I believe the most common use of rest is with disjoint types. (Spread is similar, but identical types is the most common use there.)
One way to allow this is to create a new assignability rule:
Pick<T & U & ... & { a } & { b } & ..., Exclude<keyof T & U & ..., 'a' | 'b' | ...>> ⟹ T & U & ...
In prose, the rule is that the pick of an intersection that consists of only type parameters and object types is assignable to the intersection of the type parameters if the second argument is an Exclude, and the Exclude's first argument is
keyof
the intersection of the type parameters, and the Exclude's second argument is the keys of the intersection of the object types.Another optional is a simpler rule, where the pick of any intersection with a type parameter T is assignable to T:
Pick<T & ..., Exclude<keyof T & ..., K>> ⟹ T
Note that these rules don't cover what to do with constrained type parameters. The second rule is inaccurate enough already that it probably doesn't matter, but the first rule should probably have an additional restriction on Exclude's second argument.
Use Cases
React HOCs basically all do this.
Examples
From this comment:
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: