Что такое `as const` в TypeScript и зачем он нужен?

JuniorTypeScript · Frontend·Обновлено 30 августа 2026
Коротко
as const — это утверждение типа, которое говорит компилятору вывести самый узкий (литеральный) и неизменяемый (readonly) тип для значения вместо широкого. Используется, чтобы объекты, массивы и строки сохраняли точные литеральные значения и не мутировались.

Что делает as const

По умолчанию TypeScript при выводе типов расширяет (widening) конкретные значения до более общих типов. Например, строка "admin" превращается в тип string, а число 5 — в number. Это удобно для переменных, которые могут изменяться, но иногда мешает, когда важно сохранить именно литеральное значение.

as const — это специальное утверждение типа (const assertion), которое отключает такое расширение и делает вывод типов максимально узким:

  • строковые, числовые и булевы литералы остаются литералами, а не расширяются до string / number / boolean;
  • массивы становятся кортежами (tuple) фиксированной длины вместо обычного изменяемого массива;
  • все свойства объектов и элементы массивов помечаются как readonly.

Пример без as const

Без утверждения переменная получает широкий тип, и её можно свободно менять на любое значение того же базового типа.

Пример с as const

С утверждением тип становится точным литералом, а попытка изменить значение вызывает ошибку компиляции.

Зачем он нужен

  1. Точные литеральные типы. Часто нужно, чтобы TypeScript знал не просто string, а конкретно "GET" | "POST". Это критично для union-типов, статусов, экшенов Redux и т.д.
  2. Неизменяемость (immutability). readonly защищает от случайной мутации конфигов, констант и справочных данных прямо на уровне типов.
  3. Кортежи вместо массивов. Массив с as const превращается в кортеж с фиксированными типами по позициям, что полезно для функций, принимающих аргументы по порядку.
  4. Автоматический вывод union из объекта. В связке с typeof и keyof можно получить union значений объекта без дублирования типов вручную — не нужно писать тип отдельно, он выводится из самих данных.
  5. Совместимость с строгими API. Многие библиотеки (например, для роутинга или конфигурации) ожидают литеральные типы, и as const — самый простой способ их получить без явного описания интерфейсов.

Ограничения

  • as const делает только поверхностный (shallow) readonly для вложенных структур, но применяется рекурсивно ко всем уровням вложенности объекта или массива — то есть вложенные объекты тоже становятся readonly, а не только верхний уровень.
  • Это чисто компиляторная проверка: в рантайме объект остаётся обычным изменяемым JS-объектом, readonly не защищает от мутации через as или сторонний код.
  • Нельзя применить к переменным, объявленным через let, если хочется получить пользу — обычно as const сочетают с const, иначе логика теряет смысл, хотя технически применить можно.

Итог

as const — простой и дешёвый способ получить более строгую типобезопасность без написания дополнительных интерфейсов: он сужает типы до литералов и делает данные неизменяемыми на уровне типов, что особенно полезно для конфигов, enum-подобных структур и строгих API.

Что хочет услышать интервьюер

Кандидат объясняет разницу между widening (расширением) типов и литеральными типами

Упоминает, что as const делает объект readonly, а массив — кортежем

Приводит пример практического применения: конфиги, статусы, экшены, роутинг

Понимает, что это только compile-time проверка, в рантайме объект остаётся изменяемым

Может показать связку as const с typeof и keyof для вывода union-типа

Пример: Widening без as const

// без as const тип расширяется до string
const role = "admin";
// TypeScript выводит тип: string

let method = "GET";
// тип: string, можно присвоить любую строку
method = "что угодно"; // не будет ошибки

Пример: Литеральные типы и readonly с as const

// тип выводится как литерал "admin", а не string
const role = "admin" as const;

const config = {
  method: "GET",
  retries: 3,
} as const;
// тип: { readonly method: "GET"; readonly retries: 3 }

config.method = "POST"; // ошибка компиляции: свойство readonly

Пример: Массив превращается в кортеж

const point = [10, 20] as const;
// тип: readonly [10, 20], а не number[]

function move([x, y]: readonly [number, number]) {
  console.log(x, y);
}

move(point); // подходит, так как тип точно совпадает

Пример: Вывод union-типа из объекта

const ROLES = {
  admin: "admin",
  user: "user",
  guest: "guest",
} as const;

// автоматически получаем union "admin" | "user" | "guest"
type Role = typeof ROLES[keyof typeof ROLES];

function setRole(role: Role) {
  // ...
}

setRole(ROLES.admin); // ок
setRole("hacker"); // ошибка: не входит в union

Типичные ошибки

Путают as const с обычным приведением типа (type casting) as SomeType

Считают, что readonly от as const защищает данные в рантайме

Не знают, что as const превращает массив в кортеж фиксированной длины

Забывают, что as const применяется рекурсивно ко всем вложенным свойствам

Не могут привести пример, где as const реально решает проблему (например, вывод union из объекта)

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее