Оператор satisfies у TypeScript
Що таке оператор satisfies?
Оператор satisfies (впроваджений у TypeScript 4.9) дозволяє вам перевіряти, що значення відповідає типу, зберігаючи його звужений (більш специфічний) тип — на відміну від анотації типу, яка його розширює.
Проблема, яку вирішує satisfies
typescript
type Colors = Record<string, string | number[]>;
// З анотацією типу — втрачає специфічність
const colors: Colors = {
red: "#ff0000",
green: [0, 255, 0],
};
colors.red.toUpperCase(); // ❌ Помилка: Властивість 'toUpperCase' не існує в типі 'string | number[]'
colors.green.map(x => x); // ❌ Помилка: та ж причина
// З satisfies — зберігає звужені типи
const colors = {
red: "#ff0000",
green: [0, 255, 0],
} satisfies Colors;
colors.red.toUpperCase(); // ✅ TypeScript знає, що це рядок
colors.green.map(x => x); // ✅ TypeScript знає, що це number[]Як це працює
| Підхід | Перевіряє тип? | Зберігає звужений тип? |
|---|---|---|
const x: Type = value | ✅ | ❌ (розширено до Type) |
const x = value as Type | ❌ (немає реальної перевірки) | ❌ |
const x = value satisfies Type | ✅ | ✅ |
Практичні випадки використання
Об'єкти конфігурації
typescript
type Route = {
path: string;
method: "GET" | "POST" | "PUT" | "DELETE";
handler: string;
};
type Routes = Record<string, Route>;
const routes = {
getUsers: {
path: "/api/users",
method: "GET",
handler: "UserController.getAll",
},
createUser: {
path: "/api/users",
method: "POST",
handler: "UserController.create",
},
} satisfies Routes;
// TypeScript знає точні ключі: "getUsers" | "createUser"
// І точні типи методів: "GET", "POST" (не просто об'єднання)
routes.getUsers.method; // "GET" (не "GET" | "POST" | "PUT" | "DELETE")Визначення теми
typescript
type Theme = Record<string, string | { light: string; dark: string }>;
const theme = {
primary: "#007bff",
background: { light: "#ffffff", dark: "#1a1a2e" },
text: { light: "#000000", dark: "#e0e0e0" },
} satisfies Theme;
// TypeScript зберігає структуру
theme.primary.toUpperCase(); // ✅ знає, що це рядок
theme.background.light; // ✅ знає, що це об'єкт з .lightКонстанти, схожі на enum
typescript
type StatusCode = 200 | 201 | 400 | 401 | 404 | 500;
const STATUS = {
OK: 200,
CREATED: 201,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
NOT_FOUND: 404,
SERVER_ERROR: 500,
} satisfies Record<string, StatusCode>;
// STATUS.OK — це 200 (літерал), а не просто StatusCode
type OkStatus = typeof STATUS.OK; // 200У поєднанні з as const
typescript
const palette = {
red: "#ff0000",
green: "#00ff00",
blue: "#0000ff",
} as const satisfies Record<string, `#${string}`>;
// Значення є лише для читання, літеральні типи І перевірені як шістнадцяткові кольориВажливо:
Використовуйте satisfies, коли ви хочете перевірити, що значення відповідає типу, зберігаючи при цьому більш специфічну інформацію про тип. Це підхід, який поєднує в собі найкраще з обох світів — безпеку типів без втрати звуження типів. Це особливо корисно для об'єктів конфігурації, визначень тем і карт констант.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.