Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Безпека коду і narrowing». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Narrowing підвищує безпеку коду тим, що TypeScript гарантує: у певній гілці змінна дійсно має конкретний тип, і звертання до її властивостей або методів безпечне. **Ключове:** завдяки narrowing помилки на кшталт звернення до неіснуючої властивості чи виклику методу у `null`/`undefined` ловляться на етапі компіляції, а не в рантаймі.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Запобігає зверненню до неіснуючих властивостей Без narrowing TypeScript не може знати, які поля доступні, і міг би допустити небезпечне звернення. ```javascript function printId(id: string | number) { console.log(id.toUpperCase()); // Помилка: у number немає toUpperCase } ``` З narrowing: ```javascript function printId(id: string | number) { if (typeof id === "string") { console.log(id.toUpperCase()); // безпечно } else { console.log(id.toFixed(2)); // безпечно } } ``` **Чому безпечно:** TypeScript **гарантує**, що в першій гілці `id` - точно `string`, а в другій - `number`. Помилки несумісності будуть спіймані **під час компіляції**, а не в рантаймі. --- ## 2. Виключає "неможливі" сценарії виконання Звуження типів дозволяє компілятору аналізувати потік керування і *прибирати недосяжні гілки коду*. ```javascript function process(value: string | null) { if (value === null) return; // Тут value гарантовано string console.log(value.toUpperCase()); // безпечно } ``` Без перевірки `if (value === null)`, виклик `toUpperCase()` міг би призвести до **помилки під час виконання** (`Cannot read properties of null`). --- ## 3. Робить код самодокументованим і очевидним Звуження - це не лише про захист, а й про **читабельність**: ```javascript type Response = | { status: "success"; data: string } | { status: "error"; message: string }; function handle(res: Response) { if (res.status === "success") { console.log(res.data); // безпечно } else { console.log(res.message); // безпечно } } ``` TypeScript використовує дискримінатор `status`, розуміє, який варіант активний, і підказує лише допустимі властивості в IDE. **Перевага:** жодних "випадкових" звернень до `res.data` у хибній гілці. IDE просто не дасть це зробити. --- ## 4. Знижує ймовірність помилок `undefined` і `null` Одні з найчастіших рантайм-помилок у JS: > `Cannot read property 'x' of undefined` Звуження типів допомагає виключити такі ситуації **ще до запуску**: ```javascript function showUser(user?: { name: string } | null) { if (!user) return; // відсікаємо undefined і null console.log(user.name); // точно існує } ``` TS "бачить", що після `if (!user) return` змінна `user` **не може бути** `undefined | null`. А отже, доступ до `user.name` безпечний. --- ## 5. Підвищує безпеку при роботі з union типами Без narrowing TypeScript не знає, який член об'єднання використовується. ```javascript type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number }; function area(shape: Shape) { if (shape.kind === "circle") { return Math.PI * shape.radius ** 2; // безпечно } else { return shape.side ** 2; // безпечно } } ``` Якби TS не звужував тип за `kind`, виклик `shape.radius` міг би звернутися до поля, якого немає у `square`, що призвело б до помилки в рантаймі. --- ## 6. Допомагає при логічних розгалуженнях і винятках TypeScript вміє розуміти, які типи **виключені** після `throw`, `return`, `break` тощо. ```javascript function getLength(value: string | null) { if (value === null) throw new Error("Empty value"); // Тут value точно string return value.length; // безпечно } ``` Завдяки narrowing, після `throw` TypeScript знає: `value` - не `null`. --- ## 7. Допомагає IDE підказувати коректні методи і властивості Коли тип звужений, IDE підказує лише ті методи, які реально існують у конкретного типу: ```javascript function log(x: string | Date) { if (x instanceof Date) { x.toISOString(); // підказка лише для Date } else { x.toUpperCase(); // підказка лише для string } } ``` Це **знижує ризик випадкового виклику неіснуючого методу**. Типи і автодоповнення стають контекстно-залежними. --- ## 8. Робить перевірки на повноту (exhaustiveness check) Звуження дозволяє гарантувати, що ти **обробив усі можливі варіанти типу**. ```javascript type Status = "loading" | "success" | "error"; function handle(status: Status) { switch (status) { case "loading": break; case "success": break; case "error": break; default: const _exhaustive: never = status; // Помилка, якщо з'явиться новий статус } } ``` TypeScript гарантує, що жоден варіант не пропущений. Це **абсолютний захист від логічних помилок**. --- ## 9. Допомагає безпечно працювати з `unknown` Тип `unknown` вимагає **звуження**, перш ніж до нього можна звернутися. Це захищає від помилок "наосліп": ```javascript function process(value: unknown) { if (typeof value === "string") { console.log(value.toUpperCase()); // безпечно } else { // console.log(value.toUpperCase()); // помилка - не string } } ``` TypeScript не дозволить використати `value`, поки ти не доведеш, що він безпечного типу. --- ## 10. Захищає від неправильних приведень (`as`) Без narrowing доводиться "насильно" приводити типи: ```javascript (user as { name: string }).name; // ризик - TS вірить на слово ``` З narrowing: ```javascript if (typeof user === "object" && user && "name" in user) { console.log(user.name); // безпечно, доведено логікою } ``` TypeScript не "вірить на слово" - він сам **доводить коректність** через умови. --- ## Підсумок | Що дає narrowing | Чому це безпечно | | --- | --- | | Виключає неможливі типи | TS не дозволить викликати методи неіснуючого типу | | Гарантує коректні властивості | Звернення до об'єкта лише після перевірки | | Запобігає помилкам `null` / `undefined` | Компілятор знає, що значення вже не "порожнє" | | Спрощує перевірки | IDE знає контекст і підказує правильні методи | | Забезпечує вичерпну обробку union-типу | Не можна забути жоден варіант | | Мінімізує runtime-помилки | Помилки ловляться під час компіляції |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.