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

Навіщо as const і readonly і як вони захищають дані від випадкових змін?

as const каже TypeScript вивести найвужчий тип і зробити все лише для читання:

const roles = ['admin', 'editor', 'viewer'];            // string[]
const roles2 = ['admin', 'editor', 'viewer'] as const;  // readonly ['admin', 'editor', 'viewer']

type Role = (typeof roles2)[number];   // 'admin' | 'editor' | 'viewer'

roles2.push('guest');   // помилка: масив лише для читання

Головний прийом - одне джерело правди для значень і типу. Список значень потрібен і під час виконання (випадний список, валідація), і як тип. З as const тип виводиться зі значень, і вони не розходяться:

const ORDER_STATUSES = ['new', 'paid', 'shipped'] as const;
type OrderStatus = (typeof ORDER_STATUSES)[number];

function isOrderStatus(value: string): value is OrderStatus {
  return (ORDER_STATUSES as readonly string[]).includes(value);
}

Це часто краща альтернатива enum: звичайний JavaScript-масив без особливого синтаксису.

Об'єкти:

const config = { api: { timeout: 5000 } } as const;
config.api.timeout = 10;   // помилка - readonly на всіх рівнях

readonly у типах - для параметрів і полів, які функція не повинна змінювати:

function total(items: readonly CartItem[]): number {
  items.sort();   // помилка: sort змінює масив
  return items.reduce((sum, i) => sum + i.price, 0);
}

interface User {
  readonly id: number;
  name: string;
}

ReadonlyArray<T> / readonly T[] прибирають з типу методи, що змінюють масив (push, sort, splice).

Що варто знати:

  • це лише перевірка компілятора. Під час виконання об'єкт звичайний - змінити його можна через as any чи з JavaScript-коду. Для справжньої незмінності - Object.freeze;
  • readonly поверхневий у звичайних типах: readonly items: Item[] забороняє замінити масив, але не змінити його вміст. Для вкладених структур - readonly на кожному рівні чи утиліта на кшталт DeepReadonly;
  • масив readonly string[] не можна передати туди, де очікують string[] - функції, що не змінюють масив, варто оголошувати з readonly в параметрі.

Докладніше в документації: Const-твердження

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