JavaScript & TypeScriptМодуль 8: Продвинутый TypeScript
Union и Intersection
Объединение и пересечение типов
Цель урока
В этом уроке ты научишься:
- Создавать union типы
- Использовать intersection типы
- Применять discriminated unions
Union Types (|)
Значение может быть одним из нескольких типов:
let id: string | number;
id = "abc"; // OK
id = 123; // OK
// id = true; // Ошибка!
function printId(id: string | number) {
console.log("ID: " + id);
}Сужение типа
function printId(id: string | number) {
if (typeof id === "string") {
console.log(id.toUpperCase()); // string
} else {
console.log(id.toFixed(2)); // number
}
}Intersection Types (&)
Объединяет несколько типов в один:
type Person = {
name: string;
age: number;
};
type Employee = {
company: string;
position: string;
};
type Worker = Person & Employee;
let worker: Worker = {
name: "Иван",
age: 25,
company: "Tech Corp",
position: "Разработчик"
};Discriminated Unions
Union с общим полем-дискриминатором:
type Circle = {
kind: "circle";
radius: number;
};
type Rectangle = {
kind: "rectangle";
width: number;
height: number;
};
type Shape = Circle | Rectangle;
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rectangle":
return shape.width * shape.height;
}
}
let circle: Circle = { kind: "circle", radius: 5 };
console.log(getArea(circle)); // 78.54...Exhaustive Check
Проверка, что обработаны все варианты:
type Shape = Circle | Rectangle | Triangle;
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rectangle":
return shape.width * shape.height;
default:
// Если забыли Triangle, будет ошибка
const _exhaustive: never = shape;
return _exhaustive;
}
}Практические примеры
Результат операции
type Success<T> = {
success: true;
data: T;
};
type Failure = {
success: false;
error: string;
};
type Result<T> = Success<T> | Failure;
function fetchUser(id: number): Result<{ name: string }> {
if (id > 0) {
return { success: true, data: { name: "Иван" } };
}
return { success: false, error: "Неверный ID" };
}
let result = fetchUser(1);
if (result.success) {
console.log(result.data.name); // TypeScript знает, что data есть
} else {
console.log(result.error);
}Практика
Задание 1: Union
Задача: Создай функцию для форматирования значения.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
HELLO 3.14
Задание 2: Intersection
Задача: Объедини два типа.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
Иван 25
Задание 3: Discriminated Union
Задача: Создай union для событий.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
Клик по кнопке Нажата клавиша Enter
Проверь себя
- Чем union отличается от intersection?
- Что такое discriminated union?
- Зачем нужен exhaustive check?