Перетин типів
1. Що таке перетин типів (Intersection Types)
Перетин типів (
&) - це спосіб об'єднати кілька типів в один, щоб отриманий тип містив усі властивості та методи всіх об'єднаних типів.
Простіше кажучи:
Intersection = тип, який відповідає всім об'єднаним типам одразу.
Синтаксис
type Combined = TypeA & TypeB;Тепер змінна типу
Combinedмає відповідати іTypeA, іTypeB.
Приклад
type Person = { name: string };
type Contact = { email: string };
type User = Person & Contact;
const u: User = {
name: "Tim",
email: "tim@example.com",
};Об'єкт u повинен містити і name, і email,
тому що тип User об'єднує обидва.
2. Перетини з інтерфейсами
Працює однаково з interface і type:
interface Position {
x: number;
y: number;
}
interface Shape {
color: string;
}
type ColoredPoint = Position & Shape;
const point: ColoredPoint = {
x: 10,
y: 20,
color: "red",
};3. Перетини можна робити між різними структурами
type Identifiable = { id: number };
type Timestamped = { createdAt: Date };
type Entity = Identifiable & Timestamped;
const post: Entity = {
id: 1,
createdAt: new Date(),
};Тепер
Entityвимагає іid, іcreatedAt.
4. Перетин несумісних типів
Якщо в типів, що перетинаються, є однакові поля з різними типами,
TypeScript вважатиме їх несумісними (результатом буде never).
type A = { value: string };
type B = { value: number };
type C = A & B;
// value має бути і string, і number -> неможливо
const c: C = { value: "123" }; // Помилка
C["value"]тут матиме типnever, тобто "неможливе значення".
5. Перетини та union-типи (можна комбінувати)
Можна будувати складні типи, поєднуючи | і &.
type Admin = { role: "admin"; permissions: string[] };
type User = { role: "user"; name: string };
type Person = (Admin | User) & { id: number };Тепер:
Personможе бути абоAdmin, абоUser;- але завжди повинен мати
id.
const p1: Person = { id: 1, role: "admin", permissions: ["delete"] };
const p2: Person = { id: 2, role: "user", name: "Tim" };Все коректно.
6. Перетини та класи
Перетин можна використовувати, щоб об'єднати кілька інтерфейсів без успадкування:
interface Flyable {
fly(): void;
}
interface Swimmable {
swim(): void;
}
type Duck = Flyable & Swimmable;
const duck: Duck = {
fly: () => console.log("Flies"),
swim: () => console.log("Swims"),
};Те саме можна було б зробити через
interface Duck extends Flyable, Swimmable, але&працює і дляtype, і дляinterface, і для примітивів.
7. Перетини з примітивами
Так, перетини можливі і для простих типів, але рідко корисні:
type T = string & number; // never (неможливий тип)Тому що значення не може бути одночасно і рядком, і числом.
У цьому разі перетин дає
never.
8. Перетини та узагальнені типи (Generics)
function merge<T, U>(a: T, b: U): T & U {
return { ...a, ...b };
}
const result = merge({ name: "Tim" }, { age: 25 });
// result має тип { name: string; age: number }Дуже частий прийом - "склеїти" об'єкти в один з типом, що містить об'єднані властивості.
9. Перетини проти успадкування інтерфейсів
| Особливість | extends | & (перетин) |
|---|---|---|
| Використовується з | interface | type і interface |
| Об'єднує структури | Так | Так |
Дозволяє комбінувати type + interface | Ні | Так |
| Механізм | декларативний (успадкування) | структурний (композиція) |
Простіше кажучи:
extends- це "успадкуй від батька",&- це "з'єднай обидва".
10. Де реально використовується &
-
об'єднання даних з метаданими
javascripttype WithId<T> = T & { id: string }; -
об'єднання інтерфейсів API та DTO
javascripttype Request = AuthHeaders & BodyPayload; -
об'єднання типів з опціями
javascripttype Config = BaseConfig & { debug?: boolean }; -
об'єднання класових контрактів
javascripttype Controller = HasLogger & HasRoutes;
Підсумок
Перетин типів (
&) - це механізм об'єднання кількох типів в один, який містить усі властивості всіх об'єднаних структур.Використовується, коли об'єкт повинен відповідати одразу кільком типам.
Формула проста:
A | B-> або A, або BA & B-> і A, і BПеретини ідеально підходять для:
- розширення структур даних,
- об'єднання типів з різних модулів,
- комбінування generic-типів (
T & U),- побудови потужних композиційних типів.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.