Home > front end >  How to get object value type from union of objects
How to get object value type from union of objects

Time:11-04

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.


Playground

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];
  • Related