Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим enum відрізняється від об'єднання літеральних типів і що обрати?

Задача та сама - обмежити значення фіксованим набором. Підходи різні.

enum - конструкція TypeScript, яка генерує JavaScript-код (об'єкт під час виконання):

enum Status {
  Draft = 'draft',
  Published = 'published',
}

function publish(status: Status) {}
publish(Status.Published);
publish('published');   // помилка: рядок не є Status

Об'єднання літеральних типів - лише тип, після компіляції зникає повністю:

type Status = 'draft' | 'published';

function publish(status: Status) {}
publish('published');   // ок

Аргументи на користь об'єднання:

  • нуль коду під час виконання - тип стирається;
  • сумісність зі звичайними рядками: значення з API ('published') одразу підходять, без перетворень;
  • сумісність з інструментами, що лише стирають типи: Node.js із вбудованим запуском TypeScript, erasableSyntaxOnly, швидкі транспілятори. enum - не «стиральний» синтаксис: його треба перетворювати на код, і з erasableSyntaxOnly компілятор його забороняє;
  • числові enum мають історичні дивацтва: зворотне відображення (Status[0] === 'Draft'), а у старих версіях TypeScript дозволяв присвоїти будь-яке число. З TS 5.0 присвоєння числа поза значеннями enum - помилка.

Коли потрібен ще й список значень (для <select>, валідації) - об'єкт з as const:

const STATUSES = ['draft', 'published', 'archived'] as const;
type Status = (typeof STATUSES)[number];   // 'draft' | 'published' | 'archived'

STATUSES.includes(value);   // перевірка під час виконання

Або об'єкт-«перелік»:

const Status = { Draft: 'draft', Published: 'published' } as const;
type Status = (typeof Status)[keyof typeof Status];

Один і той самий ідентифікатор - і значення, і тип: використання як в enum, але без генерації коду.

const enum вбудовує значення під час компіляції, але не працює з ізольованою транспіляцією (кожен файл окремо - Vite, esbuild) і має проблеми з бібліотеками.

Практична рекомендація: для нового коду - об'єднання літералів або as const-об'єкти. enum - якщо так прийнято в проєкті чи потрібна сумісність з наявним кодом.

Зв'язок з Laravel: PHP-енуми (enum Status: string) зручно генерувати у TypeScript як об'єднання літералів - значення збігаються з тими, що приходять у JSON.

Докладніше в документації: Enums

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання