bookmark_borderDefiniowanie enumów w TypeScript za pomocą typów literalnych

Mój ulubiony sposób definiowania typów dla enumów w TypeScript jest nieco nieintuicyjny, ale przyjemny w użytkowaniu. Najpierw definiujemy const z kluczami i wartościami, a następnie tworzymy z niego typ.

const Animal = {
   Dog: 'dog',
   Cat: 'cat'
} as const;

type Animal = typeof Animal[keyof typeof Animal];

Może się to wydawać dziwne, ponieważ tworzymy zarówno const, jak i type o tej samej nazwie, ale działa to bezproblemowo. Typu można wygodnie używać jak enuma!

if (someAnimal === Animal.Dog) {
   ...
}

To podejście daje nam code completion, jest zgodne z zasadami programowania funkcyjnego i nie generuje narzutu w runtime (w przeciwieństwie do enumów).