(Series)

How to convert an array of values into a Union type with TypeScript

Published on Tuesday, January 17, 2023

TILTypeScript

In my codebase, I have a module with a hard-coded list of values similar to this.

ts
export const values = ['hello', 'world']

In that module, I also have a function that accepts one of those values as a parameter.

ts
export const useValue = (value: 'hello' | 'world') => {
// use the value
}

To ensure the type is always kept up-to-date with the values array, I was considering the following approach.

ts
export type AllowedValue = 'hello' | 'world'
export const values: AllowedValue[] = ['hello', 'world']

While this approach works just fine, it still requires specifying the string literals in multiple places, which is... not ideal.

After a bit of reading, I realized I could narrow the type of the array from string[] to ('hello' | 'world')[] by using a const assertion.

ts
// ('hello' | 'world')[]
export const values = ['hello', 'world'] as const

Combine that with an index of the type number, and you have your union type.

ts
// 'hello' | 'world'
export type AllowedValue = typeof values[number]

Goodbye, repetition!