Теорія множин
Основна ідея
У TypeScript типи можна розглядати як множини значень. Тоді:
string- множина всіх рядківnumber- множина всіх чисел"hello"- підмножина ({ "hello" })never- порожня множина (не містить значень)unknown- універсум (множина всіх можливих значень)
На цьому тлі оператори | і & поводяться точнісінько як операції над множинами.
1. Union (|) = Об'єднання множин
Union об'єднує всі можливі значення з обох множин. Тобто значення може належати хоча б одному з об'єднуваних типів.
type T = string | number;У термінах множин:
T = Strings ∪ NumbersT включає всі рядки і всі числа.
Приклади:
let x: string | number;
x = "hello"; // елемент множини рядків
x = 42; // елемент множини чисел
x = true; // не входить в об'єднання2. Intersection (&) = Перетин множин
Intersection - це значення, які належать одночасно обом типам.
type T = A & B;У термінах множин:
T = A ∩ BT включає лише ті значення, що підходять і типу A, і типу B одночасно.
Приклад: string & number
Strings ∩ Numbers = ∅Порожня множина -> у TypeScript це never.
type Impossible = string & number; // neverПриклад: перетин об'єктів
type A = { name: string };
type B = { age: number };
type C = A & B; // { name: string; age: number }Це "перетин множин об'єктів", де значення повинні задовольняти обидві умови -> містять обидва поля.
3. Математична аналогія
| Операція TypeScript | Математичний аналог | Символ | Сенс |
|---|---|---|---|
A | B | Об'єднання множин | ∪ | «АБО» - елемент хоча б в одній з множин |
A & B | Перетин множин | ∩ | «І» - елемент одразу в обох множинах |
never | Порожня множина | ∅ | Не містить елементів |
unknown | Універсум (усі значення) | Ω | Містить усе |
extends | Підмножина | ⊆ | Тип A - підтип B |
A extends B ? X : Y | Умова належності | - | Якщо A ⊆ B, то X, інакше Y |
4. Візуальна аналогія (діаграми Венна)
A = { string }
B = { number }Union:
_______ _______
( ) ( )
\ / \ /
\ A /___________\ B /Усі елементи з A або B.
Intersection:
_______ _______
( ) ( )
\ /¯¯¯¯¯¯¯¯\ /
\ A / ∩ \ B /
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯Лише спільна частина.
5. Підмножини і "extends"
extends у TypeScript буквально відповідає поняттю "підмножина":
type A = "a" | "b";
type B = "a" | "b" | "c";
type Test = A extends B ? true : false; // true (A ⊆ B)А от навпаки - ні:
type Test2 = B extends A ? true : false; // false (B ⊄ A)6. Перетин і об'єднання на конкретних значеннях
type X = "a" | "b";
type Y = "b" | "c";
type Union = X | Y; // "a" | "b" | "c" -> ∪
type Intersection = X & Y; // "b" -> ∩| Тип | Математика | Значення |
|---|---|---|
| Union | "a" | "b" | "c" | об'єднання всіх варіантів |
| Intersection | "b" | лише спільне |
7. Інтуїтивне порівняння
| Концепція | Union (|) | Intersection (&) |
|---|---|---|
| Логічний зміст | «АБО» | «І» |
| Множини | об'єднання | перетин |
| Типізація | значення повинне бути хоча б одним типом | значення повинне задовольняти всі типи |
| Часто використовується для | варіантів, станів, enum-like типів | комбінування інтерфейсів, mixin-типів |
| Приклад | "A" | "B" | {A} & {B} |
8. Чому перетин об'єктів - не те саме, що перетин множин значень
Важливо розуміти:
- Для примітивів перетин = спільне значення.
- Для об'єктів перетин - це об'єднання полів, тому що об'єкт повинен задовольняти всі обмеження одразу.
Це логічно еквівалентно перетину множин предикатів, а не самих значень.
ПІДСУМОК
| TypeScript | Теорія множин | Сенс |
|---|---|---|
A | B | A ∪ B | Об'єднання типів |
A & B | A ∩ B | Перетин типів |
never | ∅ | Порожня множина |
unknown | Ω | Усі можливі значення |
extends | ⊆ | Перевірка підтипу / підмножини |
Просте визначення:
Union (
\|) - об'єднання типів: значення належить хоча б одній множині.Intersection (
&) - перетин типів: значення повинне належати всім множинам одночасно.Це рівно ті самі операції, що й об'єднання (∪) та перетин (∩) в теорії множин.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.