Звуження (narrowing) - TypeScript аналізує перевірки в коді й усередині гілки вважає тип вужчим, ніж оголошений.
function format(value: string | number | null) {
if (value === null) return '-';
if (typeof value === 'number') {
return value.toFixed(2); // тут value: number
}
return value.trim(); // а тут value: string
}
Що звужує тип:
typeof x === 'string',x instanceof Date,Array.isArray(x);- перевірки на
null/undefinedі на істинність; 'field' in obj- чи є властивість;- порівняння з літералом (
status === 'paid') - основа discriminated unions; - ранній
returnчиthrow: після них тип уже звужено до кінця функції.
Власний type guard - функція з типом повернення value is T:
interface Cat { meow(): void }
interface Dog { bark(): void }
function isCat(animal: Cat | Dog): animal is Cat {
return 'meow' in animal;
}
if (isCat(pet)) pet.meow();
Assertion function - кидає виняток, якщо умова не виконана, і звужує тип після виклику:
function assertDefined<T>(value: T): asserts value is NonNullable<T> {
if (value == null) throw new Error('Значення відсутнє');
}
Пастка: type guard - це обіцянка, яку компілятор не перевіряє. Якщо isCat повертає true для собаки, TypeScript повірить. Тому логіка в guard має бути простою й надійною, а для даних ззовні краще схема валідації.