Skip to content

Звуження типів у TypeScript пояснені

Способи, якими TypeScript звужує тип усередині гілки, згруповані за технікою: вбудовані guard'и, власні предикати, assertion-функції, discriminated union'и, потік рівності та truthiness, а також звуження через псевдоніми та відкладене. Кожен рядок поєднує техніку з однорядковим прикладом.

Звуження — це те, як TypeScript перетворює широкий тип на вужчий усередині гілки коду, щоб довести безпечність доступу до властивості. Кожна перевірка (typeof, in, предикат, дискримінатор) каже компілятору: звідси значення є конкретнішим. Техніки нижче — робочий набір.

Довідкова таблиця · 23 записи
23 of 23 rows
Вбудовані guard'и
Звужує примітиви: string, number, boolean та інші.if (typeof x === 'string') x.toUpperCase()
Звужує до екземпляра класу або конструйованого типу.if (e instanceof Error) e.message
Звужує, перевіряючи наявність властивості на значенні.if ('id' in obj) obj.id
Звужує будь-яке значення до масиву; union — до його члена-масиву.if (Array.isArray(x)) x.map(f)
Власні guard'и
Функція-предикат, чий результат звужує аргумент.function isUser(x): x is User { return !!x.id }
Предикат може звужувати до union'у типів, а не лише до одного.function isKey(x): x is string | number
Предикат-перетин зберігає вхідний тип і додає до нього поля.function hasId(x): x is x & { id: string }
Assertion-функція, яка кидає виняток, якщо x не є цим типом.function assertUser(x): asserts x is User
Discriminated union'и
Звужує union за спільним literal-полем через switch або if.type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
Кожен case звужує до одного члена union'у.switch (u.kind) { case 'a': u.a }
Звужує union без тегу, коли властивість є лише в одного члена.if ('b' in u) u.b
Кожен case — умова; відповідний case звужує значення.switch (true) { case typeof x === 'string': }
Гілка default привласнює значення never, доводячи повноту switch.default: { const x: never = u }
Рівність & потік
Видаляє null та undefined після перевірки рівності.if (x === null) return; x.toFixed()
Видаляє falsy-значення (0, '', null, undefined, NaN).if (!x) return; // x is defined here
Truthy-властивість у ланцюжку доводить наявність базового значення.if (user?.active) user.name
Non-null assertion видаляє null та undefined без перевірки.x!.toFixed(2)
Definite assignment: оголошує, що x привласнюється до читання.let name!: string; init()
Звуження діє всередині гілки та після ранніх return.if (!arr) return; arr.map(...)
Псевдоніми & відкладене
Const-булеве значення з перевіркою звужує там, де його тестують.const isStr = typeof x === 'string'; if (isStr) …
Const-змінна зберігає звуження в замиканнях, що її захоплюють.const s = get(); if (s) use(() => s.length)
Починаючи з TS 5.4, let або параметр лишається звуженим у замиканнях після останнього привласнення.let n: string | null = get(); if (n) use(() => n.length)
unknown не можна використати, поки guard не звузить його до реального типу.if (typeof u === 'string') u.length