Today I Learned (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.

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

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

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.

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.

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

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

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

Goodbye, repetition!

Enjoy my latest posts delivered directly to your inbox