Загрузка…
Загрузка…
TypeScript · middle · сложность 5
Union говорит: значение — один из нескольких типов, например string | number. Narrowing — процесс, которым TypeScript сужает union до конкретного типа внутри блока по проверкам (typeof, in, сравнения).
С union разрешены только операции, безопасные для всех членов. Специфичные методы — после доказательства, какой именно член. Это и есть narrowing.
Типичные способы:
typeof value === "string" — для примитивов."prop" in object — различить объекты по полям.if (status === "error").type / kind); switch по нему сужает автоматически.Бонус: в default присвоить значение в never — exhaustiveness check: добавили вариант в union и забыли ветку — компилятор ругается.
// Simple union + narrowing with typeof
function format(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase(); // here it's string
}
return value.toFixed(2); // here it can only be number
}
// Discriminated union: the "kind" field is the discriminant
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2; // TypeScript knows it's Circle
case "square":
return shape.side ** 2; // here it's Square
default: {
// Exhaustiveness: if a shape is added and we don't handle it, this won't compile
const nothing: never = shape;
return nothing;
}
}
}
// Narrowing with "in" for objects without a discriminant
type Dog = { bark: () => void };
type Cat = { meow: () => void };
function makeSound(animal: Dog | Cat): void {
if ("bark" in animal) animal.bark();
else animal.meow();
}Вызвать метод без сужения:
function shout(value: string | number) {
// return value.toUpperCase();
// Error: Property 'toUpperCase' does not exist on type 'string | number'.
// Fix: narrow first
if (typeof value === "string") return value.toUpperCase();
return String(value);
}Junior часто «лечит» это через as string или any. Это глушит ошибку; narrowing решает безопасно.
Union — «один из»; narrowing — доказательство, какой именно; discriminated unions + never дают исчерпывающий разбор состояний.