Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке type narrowing?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Type narrowing** (звуження типу) - це процес, у якому TypeScript розуміє, який конкретно тип має значення в певній гілці коду, і звужує загальний тип до більш конкретного. **Ключове:** якщо змінна може мати кілька типів (наприклад, `string | number`), TypeScript звужує цей набір, коли робиш перевірки на кшталт `typeof`, `in`, `instanceof` тощо.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке **Type Narrowing** (звуження типу) **Type narrowing** - це процес, у якому TypeScript **розуміє, який конкретно тип** має значення **в певній гілці коду** і **звужує** загальний тип до більш конкретного. > Простіше кажучи: > Якщо змінна може мати кілька типів (наприклад, `string | number`), > TypeScript "звужує" цей набір, коли ти робиш перевірки на кшталт `typeof`, `in`, `instanceof` тощо. --- ## Приклад 1. Звуження через `typeof` ```javascript function printId(id: string | number) { if (typeof id === "string") { // Тут id: string console.log("Рядок:", id.toUpperCase()); } else { // Тут id: number console.log("Число:", id.toFixed(2)); } } ``` TypeScript сам розуміє: - всередині `if (typeof id === "string")` -> `id` став `string` - всередині `else` -> `id` став `number` --- ## Приклад 2. Звуження через `instanceof` ```javascript class User { constructor(public name: string) {} } class Admin { constructor(public name: string, public permissions: string[]) {} } function printPerson(person: User | Admin) { if (person instanceof Admin) { // Тут person: Admin console.log("Права:", person.permissions); } else { // Тут person: User console.log("Звичайний користувач:", person.name); } } ``` --- ## Приклад 3. Звуження через `in` (наявність властивості) ```javascript type User = { name: string }; type Admin = { name: string; permissions: string[] }; function printInfo(person: User | Admin) { if ("permissions" in person) { // person: Admin console.log("Права:", person.permissions); } else { // person: User console.log("Ім'я:", person.name); } } ``` > `in` перевіряє наявність властивості, > і TypeScript використовує це для логічного звуження типів. --- ## Приклад 4. Звуження через `==`, `===`, `!==`, `!=` TypeScript теж вміє "розуміти" тип після таких перевірок: ```javascript function process(value: string | null) { if (value !== null) { // value: string console.log(value.toUpperCase()); } } ``` --- ## Приклад 5. Звуження через "truthy/falsy" значення TypeScript знає, що `null`, `undefined`, `0`, `""`, `false` - "falsy" значення. ```javascript function printName(name?: string) { if (name) { // name: string console.log("Привіт,", name.toUpperCase()); } else { // name: undefined console.log("Ім'я не вказано"); } } ``` --- ## Приклад 6. Користувацькі перевірки типів (Type Guards) Можна створити **свою функцію**, яка допомагає TypeScript звужувати тип: ```javascript type User = { name: string }; type Admin = { name: string; permissions: string[] }; function isAdmin(person: User | Admin): person is Admin { return "permissions" in person; } function handle(person: User | Admin) { if (isAdmin(person)) { // Тут TS знає, що person: Admin console.log("Права:", person.permissions); } else { // Тут person: User console.log("Користувач:", person.name); } } ``` > `person is Admin` - це **user-defined type guard**, > який повідомляє TS, який саме тип повернеться з перевірки. --- ## Приклад 7. Звуження всередині `switch` ```javascript type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number } | { kind: "triangle"; base: number; height: number }; function getArea(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.side ** 2; case "triangle": return (shape.base * shape.height) / 2; } } ``` > Тут TypeScript використовує **дискриміноване об'єднання** > і автоматично звужує тип у кожній гілці `case`. --- ## Де використовується type narrowing | Сценарій | Приклад перевірки | | --- | --- | | Примітиви | `typeof value === "string"` | | Класи | `instanceof SomeClass` | | Об'єкти | `"prop" in obj` | | Порівняння | `if (x !== null)` | | Булеві перевірки | `if (value)` | | Власні функції-охоронці | `value is Type` | | switch-дискримінація | `case "circle": …` | --- ## Навіщо це потрібно Type narrowing дозволяє: - працювати **без помилок** при union-типах; - отримувати **автодоповнення і підказки** в IDE; - писати **безпечний і читабельний код** без зайвих приведень типів (`as`). --- ### Коротко: > **Type narrowing** - це коли TypeScript "розуміє", > який саме тип у змінної в певний момент, > і автоматично **звужує загальний тип** до конкретного в різних гілках коду.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.