Skip to main content
Практика завдань

Константні твердження (as const) у TypeScript

Що таке as const?

as const — це асерція const, яка вказує TypeScript виводити найвужчий можливий тип для значення — роблячи його глибоко readonly з літеральними типами замість розширених типів.


Без vs З as const

typescript
// Без as const — розширені типи const config = { url: "https://api.example.com", port: 3000, methods: ["GET", "POST"] }; // тип: { url: string; port: number; methods: string[] } // З as const — звужено до літералів і readonly const config = { url: "https://api.example.com", port: 3000, methods: ["GET", "POST"] } as const; // тип: { // readonly url: "https://api.example.com"; // readonly port: 3000; // readonly methods: readonly ["GET", "POST"]; // }

Що робить as const

АспектБез as constЗ as const
Строкові значенняstringЛітеральне ("точне значення")
Числові значенняnumberЛітеральне (42)
Властивості об'єктаЗмінніreadonly
МасивиЗмінний масивreadonly кортеж
Вкладені об'єктиЗмінніГлибоко readonly

Загальні випадки використання

Створення об'єднань типів з значень

typescript
const ROLES = ["admin", "editor", "viewer"] as const; type Role = typeof ROLES[number]; // "admin" | "editor" | "viewer" const STATUS = { PENDING: "pending", ACTIVE: "active", INACTIVE: "inactive", } as const; type Status = typeof STATUS[keyof typeof STATUS]; // "pending" | "active" | "inactive"

Альтернатива Enum

typescript
// Замість enum: enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } // Використовуйте as const: const Direction = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT", } as const; type Direction = typeof Direction[keyof typeof Direction]; // "UP" | "DOWN" | "LEFT" | "RIGHT"

Функція з літеральним поверненням

typescript
function getConfig() { return { theme: "dark", lang: "en", features: ["search", "notifications"], } as const; } const config = getConfig(); config.theme; // "dark" (літерал, не string) config.features[0]; // "search" (літерал)

Дискриміновані об'єднання

typescript
const createAction = <T extends string, P>(type: T, payload: P) => ({ type, payload } as const); const increment = createAction("INCREMENT", { amount: 1 }); // { readonly type: "INCREMENT"; readonly payload: { readonly amount: 1 } }

Аргументи кортежу

typescript
// Без as const const args = [1, "hello"]; // (string | number)[] // З as const const args = [1, "hello"] as const; // readonly [1, "hello"] function foo(num: number, str: string) {} foo(...args); // ✅ Працює, оскільки TypeScript знає точні типи

as const vs Object.freeze

Особливістьas constObject.freeze
КолиЧас компіляціїЧас виконання
ГлибинаГлибоке readonlyПоверхневе
Літеральні типиТакНі
Ефект виконанняНемаєЗапобігає модифікації
typescript
// Для максимальної незмінності: комбінуйте обидва const config = Object.freeze({ api: "https://api.example.com", version: 1, } as const);

Важливо:

as const є необхідним для створення типобезпечних констант, альтернатив enum та літеральних об'єднань типів з значень. Це функція, що працює лише під час компіляції, з нульовими витратами під час виконання. Використовуйте її завжди, коли вам потрібно, щоб TypeScript виводив найбільш специфічний можливий тип.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань