Что такое Enum в TypeScript?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Enum в TypeScript
Enum (перечисление) в TypeScript — это способ определить набор именованных констант. Это полезная конструкция для работы с фиксированным набором значений, которые логически связаны между собой.
Числовые Enum
По умолчанию TypeScript создаёт числовые enums, где каждое значение — это число, начиная с 0:
enum Direction {
Up,
Down,
Left,
Right
}
console.log(Direction.Up); // 0
console.log(Direction.Down); // 1
console.log(Direction.Left); // 2
console.log(Direction.Right); // 3
Можно задать начальное значение:
enum StatusCode {
Ok = 200,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404
}
console.log(StatusCode.Ok); // 200
console.log(StatusCode.BadRequest); // 400
Значения автоматически инкрементируются:
enum Level {
Easy = 1,
Medium, // 2
Hard, // 3
Expert // 4
}
Строковые Enum
Если нужны строковые значения, используются строковые enums. Это более читаемо и явно:
enum Color {
Red = 'RED',
Green = 'GREEN',
Blue = 'BLUE'
}
console.log(Color.Red); // 'RED'
console.log(Color.Green); // 'GREEN'
const userColor: Color = Color.Blue;
console.log(userColor); // 'BLUE'
Строковые enums очень полезны для работы с API и базами данных:
enum UserRole {
Admin = 'admin',
Moderator = 'moderator',
User = 'user',
Guest = 'guest'
}
// Легко отправить на сервер
const sendRole = async (role: UserRole) => {
const response = await fetch('/api/user/role', {
method: 'POST',
body: JSON.stringify({ role })
});
return response.json();
};
await sendRole(UserRole.Admin); // Отправит 'admin'
Гетерогенные Enum
Можно смешивать числовые и строковые значения (хотя это редко используется):
enum Mixed {
No = 0,
Yes = 1,
Maybe = 'MAYBE'
}
console.log(Mixed.No); // 0
console.log(Mixed.Yes); // 1
console.log(Mixed.Maybe); // 'MAYBE'
Обратное отображение (Reverse Mapping)
Числовые enums поддерживают обратное отображение:
enum Status {
Active = 1,
Inactive = 2
}
console.log(Status.Active); // 1
console.log(Status[1]); // 'Active' — обратное отображение!
console.log(Status[2]); // 'Inactive'
За кулисами это компилируется в:
var Status;
(function (Status) {
Status[Status['Active'] = 1] = 'Active';
Status[Status['Inactive'] = 2] = 'Inactive';
})(Status || (Status = {}));
Строковые enums такого не поддерживают:
enum Color {
Red = 'RED',
Blue = 'BLUE'
}
console.log(Color.Red); // 'RED'
console.log(Color['RED']); // undefined — обратное отображение не работает
Практические примеры в React
1. Управление состояниями
enum LoadingState {
Idle = 'idle',
Loading = 'loading',
Success = 'success',
Error = 'error'
}
interface UserState {
status: LoadingState;
data: User | null;
error: string | null;
}
const initialState: UserState = {
status: LoadingState.Idle,
data: null,
error: null
};
const reducer = (state: UserState, action: any): UserState => {
switch (action.type) {
case 'FETCH_START':
return { ...state, status: LoadingState.Loading };
case 'FETCH_SUCCESS':
return { ...state, status: LoadingState.Success, data: action.payload };
case 'FETCH_ERROR':
return { ...state, status: LoadingState.Error, error: action.payload };
default:
return state;
}
};
2. Типизация компонентов
enum ButtonVariant {
Primary = 'primary',
Secondary = 'secondary',
Danger = 'danger',
Success = 'success'
}
interface ButtonProps {
variant: ButtonVariant;
children: React.ReactNode;
onClick?: () => void;
}
const Button: React.FC<ButtonProps> = ({ variant, children, onClick }) => {
const variantStyles = {
[ButtonVariant.Primary]: 'bg-blue-500 text-white',
[ButtonVariant.Secondary]: 'bg-gray-300 text-black',
[ButtonVariant.Danger]: 'bg-red-500 text-white',
[ButtonVariant.Success]: 'bg-green-500 text-white'
};
return (
<button className={variantStyles[variant]} onClick={onClick}>
{children}
</button>
);
};
// Использование
<Button variant={ButtonVariant.Primary}>Click me</Button>
3. Фильтрация и типизация форм
enum FilterType {
All = 'all',
Active = 'active',
Completed = 'completed'
}
interface Task {
id: number;
title: string;
completed: boolean;
}
const filterTasks = (tasks: Task[], filter: FilterType): Task[] => {
switch (filter) {
case FilterType.Active:
return tasks.filter(t => !t.completed);
case FilterType.Completed:
return tasks.filter(t => t.completed);
case FilterType.All:
default:
return tasks;
}
};
Const Enum
Const enum — оптимизированная версия, которая удаляется на этапе компиляции:
const enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
const move = (direction: Direction) => {
console.log(direction);
};
move(Direction.Up); // Во время компиляции заменяется на 'UP'
Компилируется в:
const move = (direction) => {
console.log(direction);
};
move('UP'); // Напрямую значение
Без const, обычный enum содержит весь код enum:.
Когда использовать Const Enum:
- Enum не меняется
- Нужна минимизация кода
- Не нужно динамическое получение значений
Плюсы и минусы
Плюсы:
- Типизация: компилятор проверит значения
- Читаемость кода: имена вместо магических чисел
- Автодополнение в IDE
- Легко рефакторить
const status: UserRole = 'invalid'; // Error!
const status: UserRole = UserRole.Admin; // OK
Минусы:
- Добавляют объём кода
- Числовые enums имеют обратное отображение (не всегда нужно)
- Const enums требуют знания о процессе компиляции
Альтернатива: Type Union
Можно использовать union types вместо enums:
// Вместо enum
type Color = 'red' | 'green' | 'blue';
const userColor: Color = 'red'; // OK
const userColor: Color = 'yellow'; // Error!
Это более лёгкое решение для простых случаев.
Вывод
Enum в TypeScript — это конструкция для определения набора именованных констант. Они обеспечивают типизацию и улучшают читаемость кода. Строковые enums предпочтительны для API и базы данных, а числовые используются реже. Для простых случаев можно использовать type unions вместо enums.