Пошук уроків, статей та іншого контенту
Створюйте типи, що дозволяють лише конкретні рядки, числа або булеві значення, використовуючи literal types.
Literal type — це тип, який дозволяє лише одне конкретне значення.
На відміну від типу string, що дозволяє будь-який рядок, тип "success" дозволяє тільки рядок "success":
let status: "success";
status = "success"; // правильно
// status = "error"; // помилкаLiteral types можуть описувати:
конкретні рядки;
конкретні числа;
значення true або false.
Вони корисні, коли набір допустимих значень обмежений і відомий заздалегідь.
Рядковий literal type записується як конкретний рядок у лапках:
let direction: "up";
direction = "up"; // правильно
// direction = "down"; // помилкаОднак окремий literal type рідко використовують самостійно. Частіше створюють об’єднання кількох допустимих значень:
type Direction = "up" | "down" | "left" | "right";
let playerDirection: Direction;
playerDirection = "left"; // правильно
playerDirection = "right"; // правильно
// playerDirection = "forward"; // помилкаСимвол | означає «або». Отже, змінна playerDirection може містити один із чотирьох рядків.
Literal types особливо зручні для обмеження аргументів функції:
type LogLevel = "info" | "warning" | "error";
function logMessage(level: LogLevel, message: string): void {
console.log(`[${level}] ${message}`);
}
logMessage("info", "Сервер запущено");
logMessage("error", "Не вдалося підключитися");
// logMessage("debug", "Додаткова інформація"); // помилкаТакий тип захищає від випадкової передачі непідтримуваного значення.
Числовий literal type описує одне конкретне число:
let httpSuccessCode: 200;
httpSuccessCode = 200; // правильно
// httpSuccessCode = 201; // помилкаЯк і для рядків, числа можна об’єднати в union type:
type HttpStatusCode = 200 | 201 | 400 | 401 | 404 | 500;
function handleStatus(code: HttpStatusCode): string {
if (code === 200) {
return "Запит успішний";
}
if (code === 404) {
return "Ресурс не знайдено";
}
if (code === 500) {
return "Внутрішня помилка сервера";
}
return `Отримано код ${code}`;
}
console.log(handleStatus(200));
console.log(handleStatus(404));
// handleStatus(403); // помилкаТакий підхід підходить для статус-кодів, рівнів пріоритету або інших значень із фіксованого набору.
Для булевих значень можна використовувати literal types true і false:
let isProduction: true;
isProduction = true; // правильно
// isProduction = false; // помилкаТип boolean дозволяє обидва значення:
let isEnabled: boolean;
isEnabled = true;
isEnabled = false;Натомість тип true дозволяє тільки true, а тип false — тільки false.
Булеві literal types можуть бути корисними, коли певна властивість об’єкта повинна мати строго визначене значення:
type SuccessfulResponse = {
ok: true;
data: string;
};
const response: SuccessfulResponse = {
ok: true,
data: "Дані отримано",
};
// response.ok = false; // помилкаTypeScript автоматично виводить типи змінних. Поведінка залежить від того, оголошена змінна через const чи let.
Для const значення зазвичай зберігає literal type:
const fixedStatus = "success";
// Тип: "success"Змінити fixedStatus неможливо не лише через const, а й тому, що його значення завжди залишається "success".
Для let TypeScript зазвичай розширює тип до загальнішого:
let currentStatus = "success";
// Тип: string
currentStatus = "error"; // дозволеноОскільки змінну let можна переприсвоїти, TypeScript вважає, що вона може містити будь-який рядок.
Якщо потрібно зберегти конкретний literal type для let, його можна вказати явно:
let currentStatus: "success" | "error" = "success";
currentStatus = "error"; // правильно
// currentStatus = "pending"; // помилкаПід час створення об’єкта TypeScript часто розширює тип його властивостей до загальних типів:
const settings = {
theme: "dark",
};
// Тип властивості settings.theme — stringТому такий об’єкт не завжди можна передати туди, де очікується конкретний literal type:
type Theme = "light" | "dark";
function applyTheme(theme: Theme): void {
console.log(`Використовується тема: ${theme}`);
}
const selectedTheme = {
theme: "dark",
};
// applyTheme(selectedTheme.theme); // помилка: тип string несумісний з ThemeЩоб зберегти literal types властивостей, можна використати as const:
type Theme = "light" | "dark";
function applyTheme(theme: Theme): void {
console.log(`Використовується тема: ${theme}`);
}
const selectedTheme = {
theme: "dark",
} as const;
applyTheme(selectedTheme.theme); // правильноas const повідомляє TypeScript, що значення потрібно розглядати як незмінні literal values. У цьому прикладі selectedTheme.theme має тип "dark", а не string.
type ButtonVariant = "primary" | "secondary" | "danger";
type ButtonSize = "small" | "medium" | "large";
type HttpStatus = 200 | 201 | 400 | 404 | 500;
type ButtonOptions = {
variant: ButtonVariant;
size: ButtonSize;
disabled: boolean;
};
function createButton(options: ButtonOptions): string {
const state = options.disabled ? "disabled" : "active";
return `Кнопка: variant=${options.variant}, size=${options.size}, state=${state}`;
}
function describeStatus(status: HttpStatus): string {
switch (status) {
case 200:
return "Успішна відповідь";
case 201:
return "Ресурс створено";
case 400:
return "Некоректний запит";
case 404:
return "Ресурс не знайдено";
case 500:
return "Помилка сервера";
}
}
const button = createButton({
variant: "primary",
size: "large",
disabled: false,
});
const statusDescription = describeStatus(201);
console.log(button);
console.log(statusDescription);
// createButton({
// variant: "success", // помилка: такого варіанта немає в ButtonVariant
// size: "large",
// disabled: false,
// });
// describeStatus(403); // помилка: такого коду немає в HttpStatusУ цьому прикладі literal types:
обмежують варіанти кнопки;
не дозволяють передати невідомий розмір;
обмежують список HTTP-кодів;
перевіряють помилки ще до запуску програми.
string замість union з literal typesfunction setTheme(theme: string): void {
console.log(theme);
}
setTheme("dark");
setTheme("unknown"); // TypeScript не вважає це помилкоюЯкщо підтримуються лише конкретні значення, краще описати їх явно:
type Theme = "light" | "dark";
function setTheme(theme: Theme): void {
console.log(theme);
}
setTheme("dark");
// setTheme("unknown"); // помилкаstring і "text"string — це будь-який рядок:
let anyText: string = "hello";
anyText = "world"; // правильно"hello" — це лише один конкретний рядок:
let onlyHello: "hello" = "hello";
// onlyHello = "world"; // помилкаconst config = {
mode: "production",
};
// Тип config.mode — string, а не "production"Якщо властивість має залишатися конкретним значенням, використовуйте as const або явну анотацію типу:
type Mode = "development" | "production";
const config: { mode: Mode } = {
mode: "production",
};
const fixedConfig = {
mode: "production",
} as const;type Priority = 1 | 2 | 3;
function setPriority(priority: Priority): void {
console.log(`Пріоритет: ${priority}`);
}
setPriority(1);
// setPriority(4); // помилкаНе додавайте значення через приведення типу без потреби. Це може приховати помилку замість того, щоб виправити її.
Literal type описує одне конкретне значення.
Рядкові literal types записуються як "value".
Числові literal types записуються як конкретні числа, наприклад 200.
Булеві literal types — це true або false.
За допомогою | можна створювати union з кількох допустимих значень.
Literal types допомагають обмежити аргументи функцій і властивості об’єктів.
const часто зберігає конкретне значення як literal type, а let зазвичай розширює його до string, number або boolean.
as const зберігає literal types для значень об’єкта.