Как задать конкретную строку в интерфейсе TypeScript (литеральный тип)
Решение: литеральные типы (Literal Types) в TypeScript
Ваша задача решается с помощью литеральных типов — это тип, который представляет собой одно конкретное значение, а не множество возможных. В TypeScript можно объединять литеральные типы через | (union type), создавая набор допустимых строк.
Базовое решение
Простой и понятный способ — объявить тип-объединение строковых литералов:
type Status = "active" | "inactive" | "pending";
interface User {
name: string;
status: Status;
}
// ✅ Корректное использование
const user1: User = { name: "Alice", status: "active" };
// ❌ Ошибка компиляции: Type '"deleted"' is not assignable to type 'Status'
const user2: User = { name: "Bob", status: "deleted" };
Теперь TypeScript будет проверять, что поле status содержит только одно из трёх значений. Если попытаться присвоить любую другую строку, компилятор выдаст ошибку.
Прямое объявление в интерфейсе (без отдельного типа)
Можно указать литералы прямо в определении интерфейса, если не планируете переиспользовать тип:
interface User {
name: string;
status: "active" | "inactive" | "pending";
}
Как работают литеральные типы
- Строковый литерал — это конкретная строка, например
"active". - Объединение (
|) — позволяет переменной принимать одно из перечисленных значений. - Если значение не входит в объединение, TypeScript выдаст ошибку на этапе компиляции.
Продвинутые возможности
Вы можете использовать литеральные типы не только для строк, но и для чисел, булевых значений и даже для объектов:
// Числовые литералы
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
// Булевые литералы
type Switch = true | false; // эквивалентно boolean
// Комбинация
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
Автодополнение в IDE
При использовании литеральных типов современные редакторы (VS Code, WebStorm) показывают список возможных значений при наборе кода. Это очень удобно:
const user: User = {
name: "Alice",
status: // здесь IDE покажет подсказку: "active" | "inactive" | "pending"
};
Почему это лучше, чем enum
- Проще и короче — не нужно создавать отдельную конструкцию.
- Легче читается — сразу видно допустимые значения.
- Совместимость с JSON — при сериализации/десериализации не возникает проблем.
- Более гибко — можно комбинировать с другими типами.
Проверка типа в рантайме
Литеральные типы работают только на этапе компиляции. Если вам нужно проверять значение во время выполнения (например, при получении данных из API), используйте защитники типа (type guards):
function isValidStatus(value: string): value is Status {
return ["active", "inactive", "pending"].includes(value);
}
// Использование
const input = "active";
if (isValidStatus(input)) {
// здесь TypeScript знает, что input имеет тип Status
console.log(input.toUpperCase()); // "ACTIVE"
}
Этот подход даёт и безопасность типов на этапе компиляции, и проверку во время выполнения.
<<Альтернативный подход: использование const assertions
Если вам нужно определить набор строк, которые могут меняться в одном месте, можно использовать const assertions (as const) вместе с массивом:
const STATUSES = ["active", "inactive", "pending"] as const;
type Status = typeof STATUSES[number]; // "active" | "inactive" | "pending"
interface User {
name: string;
status: Status;
}
Этот подход полезен, когда:
- У вас уже есть массив допустимых значений (например, для валидации).
- Вы хотите избежать дублирования — массив и тип используют одни и те же данные.
- Набор значений может расширяться — достаточно изменить массив, и тип обновится автоматически.
Как это работает
Ключевое слово as const делает массив readonly и выводит его элементы как литеральные типы, а не как string. Затем конструкция typeof STATUSES[number] извлекает объединение всех элементов массива.
Пример использования
function checkStatus(status: Status) {
// status может быть только "active", "inactive" или "pending"
if (STATUSES.includes(status)) {
console.log("Valid status");
}
}
Этот метод особенно популярен в проектах, где важна согласованность данных между типами и рантайм-логикой.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Кэширование в PHP: Redis, Memcached и встроенные решения для ускорения сайта