Let's say I have these types:
interface A {
a: number
b: string
c: string
}
interface B {
a: string
b: string
}
type C = A | B
I want to get the possible values of the type C
. For example
type ValueOfObject<T, K> = What should be here?
type aValues = ValueOfObject<C, 'a'> // should return number | string
type bValue = ValueOfObject<C, 'b'> // should return string
type cValues = ValueOfObject<C, 'c'> //should return string | undefined
How can i achieve it?
I manage to get all the keys from union by
type KeysOfUnion<T> = T extends T ? keyof T: never;
Cannot get the values though
CodePudding user response:
You can do it like this:
type KeysOfUnion<T> = T extends T ? keyof T: never;
type ValueOfObject<T, K extends KeysOfUnion<T>> =
T extends infer U
? K extends keyof U
? T[K]
: undefined
: never
We distribute T
over the conditional and check for each member U
if K extends keyof U
. If it does, we can return T[K]
and if not, we add undefined
to the union.
CodePudding user response:
I found out the solution:
type KeysOfUnion<T> = T extends T ? keyof T: never;
// We need to convert our union to intersection then our type would be trivial
type UnionToIntersection<T> =
(T extends any ? (x: T) => any : never) extends
(x: infer R) => any ? R : never;
type UnionValue<U, K extends KeysOfUnion<U>> = UnionToIntersection<U>[K];