export const MyEnumMapping = {
active: 0,
inactive: 1
} as const
export type MyEnum = typeof MyEnumMapping[keyof typeof MyEnumMapping];
So you have the names exposed, but the underlying type is the number. type MyEnum = {
active: 0;
inactive: 1;
}
const MyEnum: MyEnum = {
active: 0,
inactive: 1,
}
const showAge = MyEnum.active;
const showPets = MyEnum.inactive;
It's slightly more duplication, but a lot more readable (imo) to those unfamiliar to utility types. TypeScript also enforces keeping them in sync. function doSomethingWithMyEnum(val: MyEnum[keyof MyEnum])
You could do `val: number`, but now you're allowing any number at all.Ultimately, the type syntax in TypeScript is a key part of the language, and I don't think it's unreasonable to expect developers to learn the basic typeof and keyof operators. If we were talking about something wonkier like mapped types or conditional types, sure, it might make sense to avoid those for something as basic as enums.
Personally I am definitely not skilled enough at typescript to come up with this on my own before seeing this thread so this was not even an option until now.
export type MyEnum = ValueOf<MyEnumMapping>;
TypeScript not having enough sugar in its built-in utility types is definitely a fair criticism.But more to the point, the above is not usually how you do enums in TS unless you have some very specific reason to want your values to be numbers at all times. There are some cases like that, but usually you would just let the values be strings, and map them to numbers on demand if that's actually required (e.g. for a specific serialization format).
Edit: But for what it's worth, yes, the above is still more elegant than enums. The syntax may feel less elegant, but among other things, the above does not depart from the structural type paradigm that the rest of the language uses, all for something as simple as an enum.