satisfies перевіряє, що значення відповідає типу, але не замінює виведений тип значення на цей тип.
Проблема з анотацією:
type Route = { path: string; auth?: boolean };
const routes: Record<string, Route> = {
home: { path: '/' },
admin: { path: '/admin', auth: true },
};
routes.admin.path; // ok
routes.nope.path; // теж компілюється - тип каже «будь-який рядок-ключ»
Анотація Record<string, Route> «стерла» знання про конкретні ключі: TypeScript більше не знає, що є лише home і admin.
З satisfies:
const routes = {
home: { path: '/' },
admin: { path: '/admin', auth: true },
} satisfies Record<string, Route>;
routes.admin.auth; // ok
routes.nope; // помилка: такого ключа немає
Об'єкт перевірено на відповідність Route (друкарська помилка в pth чи auth: 'yes' дасть помилку), а тип лишився точним - з конкретними ключами й значеннями.
Де це корисно:
- конфігурації й мапи: маршрути, переклади, налаштування таблиць, словники статусів;
- разом з
as const- точні літеральні типи плюс перевірка форми:
const statusColors = {
paid: 'green',
pending: 'amber',
} as const satisfies Record<OrderStatus, string>;
Якщо в OrderStatus з'явиться новий статус, TypeScript вкаже, що мапа неповна.
Порівняння трьох способів:
| Запис | Перевірка | Тип значення |
|---|---|---|
const x: T = ... |
так | T (широкий) |
const x = ... as T |
майже ні | T |
const x = ... satisfies T |
так | точний виведений |
as тут - найгірший варіант: приведення типу пропускає помилки, які satisfies і анотація зловили б.