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
I don't believe this is a bug, but due to the design of distribution over unions in the conditional. In some cases I think it would be more intuitive to treat the union atomically, in particular when the union is meant to be a key set.
The context where I stumbled across this was trying to define a pick function using tuples of fields, rather than a list of union type. So I wanted something like:
Assuming that there is not an alternate encoding and this is a use case worth supporting, two possible solutions:
Do not have conditional types distribute when the condition is of the form X extends keyof Y.
Be able to box variables to prevent lifting. e.g. type PickOrNever<T, K> = [K] extends [keyof T] ? Pick<T, K> : never; Currently this wont work as keyof does not propagate from inside the tuple to the bare variable K. (K does not satisfy the constraint keyof T).
The text was updated successfully, but these errors were encountered:
I figured there was a trick I was missing and it was convincing the checker that K extends keyof T in the true branch of the conditional for the constraint in Pick.
I think this works by building the selected keys from Extract which only ever returns types from keyof T, so the result is trivially assignable to keyof T. Under the assumption K extends keyof T then Extract<keyof T, K> = K, I think.
Is the fact that extends does not propagate to the true branch when guarded by [] down to design choices, for soundness etc, or just the way the checker works.
EDIT: I think my question and example could be clearer. I guess what I was wondering was whether
Does [A] extends [B] imply A extends B?
Assuming 1. could those constraints propagate in conditional types?
E.g.
typeExtender<T,KextendsT>=K;typeExtenderTest<T,K>=KextendsT ? Extender<T,K> : never// OKtypeExtenderTestBoxed<T,K>=[K]extends[T] ? Extender<[T],[K]> : never// NOT-OK/*Type '[K]' does not satisfy the constraint '[T]'. Type 'K' is not assignable to type 'T'. [2344]*/
Uh oh!
There was an error while loading. Please reload this page.
I don't believe this is a bug, but due to the design of distribution over unions in the conditional. In some cases I think it would be more intuitive to treat the union atomically, in particular when the union is meant to be a key set.
TypeScript Version: 2.8.0
Search Terms: Conditional Types
Code
Desired behavior:
Actual behavior:
The context where I stumbled across this was trying to define a
pick
function using tuples of fields, rather than a list of union type. So I wanted something like:Assuming that there is not an alternate encoding and this is a use case worth supporting, two possible solutions:
X extends keyof Y
.type PickOrNever<T, K> = [K] extends [keyof T] ? Pick<T, K> : never;
Currently this wont work askeyof
does not propagate from inside the tuple to the bare variable K. (K does not satisfy the constraint keyof T
).The text was updated successfully, but these errors were encountered: