Оператор in при перевірці union
Що робить оператор in при перевірці union-типу
Оператор in перевіряє,
чи є вказана властивість в об'єкті -
і якщо так, TypeScript звужує тип до того варіанта union-у,
у якому ця властивість визначена.
Простіше кажучи:
inдопомагає TypeScript "зрозуміти", який саме тип об'єкта зараз перед нами.
Приклад 1. Класичний випадок
type User = { name: string };
type Admin = { name: string; permissions: string[] };
function printInfo(person: User | Admin) {
if ("permissions" in person) {
// Тут person: Admin
console.log("Права:", person.permissions);
} else {
// Тут person: User
console.log("Користувач:", person.name);
}
}TypeScript аналізує union:
Userне міститьpermissionsAdminміститьpermissions- -> усередині
ifTS звужує тип доAdmin
Приклад 2. Кілька можливих типів у union-і
type Circle = { radius: number };
type Rectangle = { width: number; height: number };
type Shape = Circle | Rectangle;
function area(shape: Shape) {
if ("radius" in shape) {
// shape: Circle
return Math.PI * shape.radius ** 2;
} else {
// shape: Rectangle
return shape.width * shape.height;
}
}TypeScript розуміє: якщо в об'єкта є
radius, отже це Circle, інакше - Rectangle.
Приклад 3. Складні типи з кількома унікальними властивостями
type Cat = { meow: () => void };
type Dog = { bark: () => void };
type Animal = Cat | Dog;
function makeSound(animal: Animal) {
if ("bark" in animal) {
// animal: Dog
animal.bark();
} else {
// animal: Cat
animal.meow();
}
}Чудовий спосіб розрізняти схожі типи без поля-дискримінатора.
Приклад 4. Перевірка у вкладених об'єктах
Оператор in також працює з вкладеними об'єктами:
type Employee = { info: { position: string } };
type Contractor = { company: string };
function describe(person: Employee | Contractor) {
if ("info" in person) {
console.log("Працівник:", person.info.position);
} else {
console.log("Контрактор:", person.company);
}
}Важливо
- Оператор
inне перевіряє значення, а лише наявність властивості в об'єкті.
const obj = { x: undefined };
console.log("x" in obj); // true (властивість є, хоча й undefined)- Перевірка працює лише з об'єктами (не з примітивами):
"length" in "hello"; // true
"x" in 42; // помилка: number не об'єктКоли використовувати in
| Коли | Чому |
|---|---|
| В union-типах з різними наборами властивостей | Чудово розрізняє форми даних |
Коли немає спільного поля-дискримінатора (kind) | Альтернатива discriminated unions |
| У користувацьких type guard-функціях | Можна вбудувати в return "prop" in obj |
Приклад користувацького Type Guard на основі in
type User = { name: string };
type Admin = { name: string; permissions: string[] };
function isAdmin(person: User | Admin): person is Admin {
return "permissions" in person;
}
function print(person: User | Admin) {
if (isAdmin(person)) {
console.log("Адмін:", person.permissions);
} else {
console.log("Користувач:", person.name);
}
}Тут
return "permissions" in person;допомагає TypeScript визначити, що функціяisAdminгарантує типAdmin.
ПІДСУМОК
Що робить in | Перевіряє наявність властивості в об'єкта |
|---|---|
| Синтаксис | "propertyName" in object |
| Повертає | true, якщо властивість існує |
| Типова дія | Звужує тип union-у до того, де властивість є |
| Працює з | Об'єктами і класами |
| Часте застосування | Для розрізнення варіантів union-типу (`User |
Коротко:
Оператор
in- це вбудований Type Guard, який допомагає TypeScript визначити, який тип з union-у зараз використовується, перевіряючи наявність певної властивості в об'єкті.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.