← Назад к вопросам

Что такое литеральные типы?

1.3 Junior🔥 202 комментариев
#TypeScript

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое литеральные типы (Literal Types) в TypeScript?

Литеральные типы — это продвинутая особенность системы типов TypeScript, позволяющая определять типы, которые принимают не диапазон значений (как string или number), а одно конкретное значение. По сути, это тип, который может быть равен только определённой строке, числу, булеву значению или элементу перечисления (enum). Они являются подмножеством примитивных типов и предоставляют мощный механизм для повышения точности типизации.

Основные виды литеральных типов

  • Строковые литералы (String Literal Types): Тип, который может быть только конкретной строкой.

    let direction: "left" | "right" | "up" | "down";
    direction = "left"; // OK
    direction = "north"; // Ошибка: Тип '"north"' не может быть назначен типу '"left" | "right" | "up" | "down"'.
    
  • Числовые литералы (Numeric Literal Types): Тип, который может быть только конкретным числом.

    function rollDice(): 1 | 2 | 3 | 4 | 5 | 6 {
        return (Math.floor(Math.random() * 6) + 1) as 1 | 2 | 3 | 4 | 5 | 6;
    }
    let diceResult: 1 | 2 | 3 = rollDice(); // Ошибка: Тип '1 | 2 | 3 | 4 | 5 | 6' не может быть назначен типу '1 | 2 | 3'.
    
  • Булевы литералы (Boolean Literal Types): Тип, который может быть только true или только false. Часто используется в паре.

    let isStrictMode: true; // Переменная может быть ТОЛЬКО true
    let isEnabled: false;   // Переменная может быть ТОЛЬКО false
    // Более полезно в объединениях (unions) или с дженериками
    type ValidationSuccess = { isValid: true; value: string };
    type ValidationError = { isValid: false; error: string };
    
  • Literals из перечислений (Enum Member Types): Каждый член перечисления (enum) в TypeScript также является литеральным типом.

    enum LogLevel {
        Debug = "DEBUG",
        Info = "INFO",
        Error = "ERROR"
    }
    function logMessage(level: LogLevel.Debug | LogLevel.Error, message: string) {
        // Функция принимает только два конкретных значения из enum
        console.log(`[${level}] ${message}`);
    }
    logMessage(LogLevel.Debug, "Starting app..."); // OK
    logMessage(LogLevel.Info, "Something happened"); // Ошибка
    

Практическая польза и применение

Литеральные типы — не просто академическая концепция. Они активно используются для:

  1. Повышения безопасности типов в ключевых функциях. Например, при работе с DOM API или HTTP-методами:

    type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
    async function fetchData(url: string, method: HttpMethod): Promise<Response> {
        return fetch(url, { method });
    }
    // Компилятор предотвратит опечатку:
    fetchData("/api/users", "POST"); // OK
    fetchData("/api/users", "PATCH"); // Ошибка: Аргумент типа '"PATCH"' не может быть назначен параметру типа 'HttpMethod'.
    
  2. Создания дискриминируемых объединений (Discriminated Unions). Это один из самых мощных паттернов в TypeScript, где литеральный тип выступает в роли "тега" (discriminant), позволяя компилятору корректно сужать (narrow) типы.

    type NetworkLoadingState = { state: "loading" };
    type NetworkFailedState = { state: "failed"; statusCode: number };
    type NetworkSuccessState = { state: "success"; response: string };
    
    type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState;
    
    function processState(networkState: NetworkState) {
        // В зависимости от конкретного литерала `state` TypeScript знает, какие поля доступны
        switch (networkState.state) {
            case "loading":
                console.log("Загрузка...");
                break;
            case "failed":
                // Здесь TypeScript гарантирует, что `statusCode` существует
                console.log(`Ошибка ${networkState.statusCode}`);
                break;
            case "success":
                // Здесь доступно `response`
                console.log(`Данные: ${networkState.response}`);
                break;
        }
    }
    
  3. Конфигурации и опций функций/компонентов. Литералы идеально подходят для описания строго ограниченного набора допустимых опций, например, позиционирования элемента или темы оформления.

    type AlertVariant = "success" | "warning" | "error" | "info";
    type TooltipPlacement = "top" | "bottom" | "left" | "right";
    
    function showAlert(text: string, variant: AlertVariant) { /* ... */ }
    
  4. Взаимодействия с const утверждениями (const assertions). Ключевое слово as const заставляет TypeScript трактовать значение как глубоко неизменяемое (readonly) и выводить максимально конкретные типы, включая литеральные.

    const colors = ["red", "green", "blue"] as const;
    // Тип colors: readonly ["red", "green", "blue"]
    // Элемент массива имеет тип литерала, а не просто `string`
    type PrimaryColor = typeof colors[number]; // "red" | "green" | "blue"
    

Вывод типа (Type Inference) и сужение (Narrowing)

TypeScript часто выводит литеральные типы автоматически, особенно для const-переменных, инициализированных примитивом:

const message = "Hello World"; // Тип: "Hello World" (строковый литерал), а не string
let count = 42; // Тип: number, так как let подразумевает возможность изменения

Сужение типа с помощью проверок (===, !==, switch) позволяет компилятору динамически определять конкретный литеральный тип внутри блоков кода, что делает логику безопасной и предсказуемой.

Заключение

Литеральные типы — это фундаментальный инструмент для написания выразительного и надёжного кода на TypeScript. Они позволяют моделировать предметную область с высокой точностью, превращая потенциальные ошибки времени выполнения (опечатки, неверные значения) в ошибки компиляции. Их использование в сочетании с объединениями (unions) и сужением типов (narrowing) составляет основу продвинутой статической типизации, которая отличает TypeScript от обычного JavaScript и значительно упрощает поддержку больших и сложных приложений.

Что такое литеральные типы? | PrepBro