how can i implement this:
type ActionNames = 'init' | 'reset';
type UnionToObj<U> = {/* TODO HERE */}
type Result = UnionToObj<ActionNames>;
// expect type Result to be `{ init: any, reset: any }`
i had written a implementation, but it not work correctly, it meets the union extends covariance problem:
type UnionToObj<U> = U extends string ? { [K in U]: any } : never;
type Result = UnionToObj<'init' | 'reset'>;
// expecting the type Result to be `{ init: any, reset: any }`
// but i got a union object: `{ init: any } | { reset: any }`
// how do i resolve it ?
main problem:
This is a straightforward mapped type :
type UnionToObj<U extends PropertyKey> = { [K in U]: any }
type Result = UnionToObj<ActionNames>;
/* type Result = {
init: any;
reset: any;
} */
Here we are constraining U
to be key-like instead of checking it via a conditional type. If you really want to do it that way, you can, with a solution like this:
type UnionToObj<U> = [U] extends [PropertyKey] ? { [K in U]: any } : never;
The difference between this and your version is that your version is unintentionally a distributive conditional type . Since you don't want union inputs to become union outputs, you need to prevent conditional type distribution by not having U extends...
directly with a bare type parameter in the checked position. Wrapping the checked type in a one-tuple ( [U] extends...
) is enough to turn off union distribution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.