WHITECOLOR
WHITECOLOR

Reputation: 26142

Get union type from indexed object values

Say I have an indexed type:

type X = {
 a: 'A',
 b: 'B'
}

is it possible to get (derived) from it:

type V = 'A' | 'B'

not using explicit method like:

type V = X['a'] | X['b']

What I want is something like keyof (for getting keys union type), but for values.

Upvotes: 44

Views: 24247

Answers (3)

random-forest-cat
random-forest-cat

Reputation: 35914

I realize this has already been answered, but if you are looking for a way to narrow your union to actual values instead of primitives and you are working with immutable state, you can do this:

const X = {
  a: 'A', 
  b: 'B'
  // mark properties as readonly, otherwise string type inferred 
} as const

type XValues = typeof X[keyof typeof X]

// "A" | "B

Alternatively, if you are working with both mutable and immutable copies, creating a separate readonly type could be useful:

const X = {
  a: 'A',
  b: 'B'
} 

type X = Readonly<typeof X>

type XValues = keyof X  

// "A" | "B

Upvotes: 49

Juan Perez
Juan Perez

Reputation: 346

In case someone wants to do this for a union of types, instead of just one type, this works perfectly:

type allSubTypesOfUnionType<T> = T extends any ? T[keyof T] : never

So if you have a union of 2 types:

type cheese = {
  name: string
  holes: number
}
type pizza = {
  slices: number
  isPepperoni: boolean
}
type yellowFood = cheese | pizza

You can then create a type that extracts all the sub-types as a union:

type possibleTypesOfYellowFood  = allSubTypesOfUnionType<yellowFood>
// types is: number | string | boolean

This was adapted from this answer that did the same but for keys instead of sub-types.

Upvotes: 4

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249646

You can use a type query with the result of keyof:

type V = X[keyof X]

Generally a type query will return a union of all possible field types, so X['a'] | X['b'] is the same as X['a' | 'b']. This is why X[keyof X] works, as keyof will return a union of string literal types representing all keys in the object.

Upvotes: 63

Related Questions