TGViewer
Frontend Alliance | Автушенко Андрей Frontend Alliance | Автушенко Андрей @frontendalliance · 2.22K subscribers
Post #114 1.19K
Пересечение и объединение типов

🟣Типы в TypeScript могут как пересекаться, так и объединяться.

Объединение множеств выполняется через вертикальную черту "|".

type StringOrNumber = string | number
type StringOrBoolean = string | boolean

const x1: StringOrNumber = 'hello'
const x2: StringOrNumber = 5
const y1: StringOrBoolean = false
const y2: StringOrBoolean = 'foo'

type Union = StringOrNumber | StringOrBoolean // string | number | boolean
type Intersected = StringOrNumber & StringOrBoolean // string


Тип StringOrNumber включает в себя все множество строк и все множество чисел. То есть мы можем создать как переменную числового значения, так и строкового.
Тип StringOrBoolean, включает в себя все множество строк и два буленовых значения false и true.

Если объединить эти два типа через |, мы получим ещё более широкий тип, который будет включать в себя все множество строк, чисел и буленовых значений.

Пересечение достигается через знак амперсанд "&"
Если мы попробуем пересечь эти два множества, то получим на выходе только string, потому что это единственное множество, которое входит в оба типа.

В TypeScript можно использовать условные типы, где тип вычисляется по условию - это похоже на тернарный оператор, но для типов.

type Union = StringOrNumber | StringOrBoolean // string | number | boolean
type Intersected = StringOrNumber & StringOrBoolean // string

type R1 = number extends Union ? 'yes' : 'no' // "yes"

type R2 = number extends Intersected ? 'yes' : 'no' // "no"

Например, мы можем проверить для прошлого примера, расширяет ли number тип Union - результат будет положительный, потому что number является подмножеством множества строк-чисел-и-буленовых значений.

А вот Intersected уже не расширяет, поэтому в итоговый тип попадет строка 'no'

🟣Нюансы объектных типов

Когда мы объединяем объектные типы, мы накладываем условие, что объект должен соответствовать хотя бы одному из указанных типов.

// Пример: состояние кнопки

type ButtonState =
| { type: 'loading'; spinner: boolean }
| { type: 'error'; message: string }
| { type: 'default'; label: string };

const btn1: ButtonState = { type: 'loading', spinner: true }; // ок
const btn2: ButtonState = { type: 'error', message: 'Oops!' }; // ок
const btn3: ButtonState = { type: 'default', label: 'Click me' }; // ок
const btn4: ButtonState = { type: 'loading', message: 'Oops!' }; // ❌ TS ругается, потому что объект должен соответствовать *только одному из вариантов*


Например, у нас есть тип ButtonState, где в зависимости от поля type может быть одно из полей: spinner, message или label.

🟣Если пересечение примитивов обычно бесполезно (так как тип не может одновременно быть и строкой и числом), то пересечение объектов (&) работает иначе: мы объединяем все свойства вместе.

// Пример: пользователь с настройками

type User = { id: number; name: string };
type Settings = { darkMode: boolean; notifications: [] };

type UserWithSettings = User & Settings;

const user1: UserWithSettings = {
id: 1,
name: 'Alice',
darkMode: true,
notifications: [],
}; // ✔️ ок

const user2: UserWithSettings = {
id: 2,
name: 'Bob',
}; // ❌ нет свойств из Settings (darkMode и notifications)


В данном примере есть два объекта:
- User с полями id и name
- Settings с полями darkMode и notifications

При пересечении этих типов (User & Settings) мы получаем новый тип, который содержит все свойства сразу: id, name, darkMode и notifications.

✈️ Telegram | 🎓 Менторство | 📹 YouTube | 👩‍💻 Roadmap
  • 🔥 23
  • ✍ 6
  • 👍 6
  • ❤ 1
More from @frontendalliance
  1. Sep 19, 2026Скам на рынке труда Скам в интернете уже давно не удивляет. Но сегодняшний скам паразитиру…
  2. Sep 15, 2026Post #141
  3. Sep 10, 2026Post #140
  4. Aug 21, 2026Post #139
  5. Aug 6, 2026Type refinements: все способы уточнить тип Type Refinement (или уточнение типа) - это проц…
  6. Jun 30, 2026WeakMap и WeakSet На защитах материала у студентов по JavaScript я регулярно вижу один и т…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →