simpler enums in typescript
Published in
1 min readFeb 10
--
i often see typescript enums used as constraints for redux actions and the like. for example:
enum ActionTypes {
GO = 'GO',
STOP = 'STOP',
}
export const goAction = createAction(ActionTypes.GO, (resolve) => {
return (payload?: any) => resolve(payload);
});
function funcThatAcceptsAnAction(action: ActionTypes) {
...
}
it would be far more concise to just do this:
enum ActionTypes {
GO,
STOP,
}
but then the value of e.g. ActionTypes.GO
is a number instead of a string, and that’s bad for action debugging.
here’s the solution.
// "library" code
type EnumKey<T> = keyof T;
type StringEnum<T> = { [K in EnumKey<T>]: K };
function createEnumProxy<T extends object>(enumObject: T): StringEnum<T> {
type MyEnumKey = EnumKey<T>;
return new Proxy(
{} as StringEnum<T>,
{
get: (target: StringEnum<T>, property: PropertyKey): MyEnumKey => {
return property as MyEnumKey;
}
}
);
}
// usage
enum ActionTypesNum {
GO,
STOP,
}
export ActionTypes = createStringEnum(ActionTypesEnum)
console.log(ActionTypes.GO) // outputs "GO"
// argument typing
type ActionType = keyof typeof ActionTypesEnum; // or keyof typeof ActionTypes
function funcThatAcceptsAnAction(action: ActionType) {
...
}