How to build a type from enum values in TypeScript?
An enum can hold string and number values.
For strings:
you can create a string union from enum values using a template string
enum FooKeys {
FOO = 'foo',
BAR = 'bar',
}
type FooValues =`${FooKeys}`; // this equals 'foo' | 'bar'
For numbers: we can either create string union the same way or:
starting TS 5.0
TypeScript 5.0 manages to make all enums into union enums by creating
a unique type for each computed member. That means that all enums can
now be narrowed and have their members referenced as types as well.
Which means:
enum MagicNumbers {
a = 1,
b = 42
}
const numberA : MagicNumbers = 1;
const numberB : MagicNumbers = 2; // will raise an error since TS 5.0
Experiment by yourself
For both:
Combining the above, we can build an EnumAsUnion
type helper as follows
enum-as-union.ts
type StringValues<T> = {
[K in keyof T]: T[K] extends string ? T[K] : never;
}[keyof T];
type NumberValues<T> = {
[K in keyof T]: T[K] extends number ? T[K] : never;
}[keyof T];
/**
* Usage : type EnumValues = EnumAsUnion<typeof anEnum>
*/
type EnumAsUnion<T> = `${StringValues<T>}` | NumberValues<T>;
Example:
import { EnumAsUnion } from 'enum-as-union';
enum anEnum {
val1 = 'a',
val2 = 'b',
val3 = 1,
val4 = 2,
}
type EnumValues = EnumAsUnion<typeof anEnum>;
let t: EnumValues;
t = 'a';
t = 'b';
t = 'c'; // error, as expected
t = 1;
t = 2;
t = 3; // error, as expected
Try it here