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).

bookmark_borderHow to define enum type in Typescript

My favorite way of defining types for enums in TypeScript is simple yet powerful, though slightly counterintuitive. First, we define a const with keys and values, then construct a type from it.

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

type Animal = typeof Animal[keyof typeof Animal];

It may feel counterintuitive because we create both a const and a type with the same name, but it works seamlessly.
We can conveniently use the type like an enum!

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

This approach offers autocompletion benefits, aligns with functional programming principles, and has zero runtime overhead (unlike enums).