Union-типы, литеральные типы и strictNullChecks
Объединяем типы через вертикальную черту и берём под контроль коварные null и undefined.
Union-тип — тип «или одно, или другое», записывается через вертикальную черту:
string | number.
Union-типы
Иногда значение может быть нескольких типов. Union перечисляет допустимые варианты:
let id: string | number;
id = 42; // ок
id = "user-7"; // ок
id = true; // Ошибка: Type 'boolean' is not assignable to type 'string | number'.
Это частая ситуация: идентификатор приходит то числом, то строкой. Union честно это описывает вместо ленивого any.
Сужение перед использованием
Со значением union-типа нельзя сразу делать операции, специфичные для одного из вариантов — нужно сначала разобраться, что это сейчас. Это называется сужением типа:
function printId(id: string | number) {
if (typeof id === "string") {
console.log(id.toUpperCase()); // тут id точно string
} else {
console.log(id.toFixed(2)); // а тут точно number
}
}
Внутри каждой ветки TypeScript знает конкретный тип и разрешает соответствующие методы. Подробнее о сужении — в последнем разделе.
Литеральные типы
Тип может быть не «любая строка», а конкретное значение. Объединяя литералы через union, получаем перечисление допустимых вариантов:
type Direction = "up" | "down" | "left" | "right";
function move(dir: Direction) { /* ... */ }
move("up"); // ок
move("north"); // Ошибка: Argument of type '"north"' is not assignable to parameter of type 'Direction'.
Это мощная защита: вместо «принимаем любую строку и надеемся» компилятор гарантирует, что придёт только одно из четырёх значений. Опечатки исключены, а редактор подсказывает варианты.
Проблема null и undefined
Главный источник падений в JavaScript — обращение к свойству у null или undefined («Cannot read property of undefined»). Опция strictNullChecks (входит в strict) защищает от этого.
Со строгими проверками null нельзя положить в обычный тип:
let name: string = null;
// Ошибка: Type 'null' is not assignable to type 'string'.
Чтобы значение могло быть пустым, это указывают явно через union:
let name: string | null = null;
Компилятор требует проверки
Теперь обратиться к свойству, не проверив на null, нельзя — и это спасает от рантайм-падения:
function greet(name: string | null) {
// name.toUpperCase(); // Ошибка: 'name' is possibly 'null'.
if (name !== null) {
console.log(name.toUpperCase()); // тут уже безопасно
}
}
Без strictNullChecks первая строка прошла бы, и программа упала бы в рантайме на null. TypeScript превращает потенциальный краш в обязательную проверку.
Итог
- Union
A | Bописывает значение нескольких типов; перед использованием его сужают. - Литеральные типы (
"up" | "down") ограничивают значение конкретным набором — защита от опечаток. strictNullChecksзаставляет явно объявлять и проверятьnull/undefined, убирая целый класс падений.