Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Навіщо потрібне звуження типів?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Звуження типів (type narrowing)** - це процес, за якого TypeScript **автоматично уточнює тип змінної** на основі логіки в коді, наприклад звужуючи `string | number` до `string` в одній гілці `if` і до `number` в іншій. **Ключове:** воно потрібне, щоб писати безпечний код без зайвих кастів `as`, отримувати точні автопідказки IDE та реалізовувати дискриміновані об'єднання й аналіз потоку керування.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке звуження типів (нагадаємо коротко) **Звуження типів (type narrowing)** - це процес, за якого TypeScript **автоматично уточнює тип змінної** на основі логіки в коді. Приклад: ```javascript function print(value: string | number) { if (typeof value === "string") { // Тут value: string console.log(value.toUpperCase()); } else { // Тут value: number console.log(value.toFixed(2)); } } ``` TypeScript **звузив** тип `value` з `string | number` до `string` і `number` у різних гілках. --- ## Навіщо це потрібно Звуження - це **фундаментальний механізм**, який робить TypeScript потужним, зручним і безпечним. Ось 6 ключових причин. --- ### 1. Щоб писати безпечний код Без narrowing TypeScript не зміг би зрозуміти, який саме тип зараз у значення. ```javascript function process(input: string | number) { console.log(input.toUpperCase()); // Помилка - а раптом input: number? } ``` З narrowing: ```javascript if (typeof input === "string") { console.log(input.toUpperCase()); // Безпечно } ``` **Результат:** менше помилок у рантаймі, тому що TS перевіряє логіку на етапі компіляції. --- ### 2. Щоб TypeScript розумів реальні гілки виконання TypeScript уміє **аналізувати потік керування** (control flow analysis). Він "розуміє", як ваші умови впливають на можливі типи. ```javascript function example(x?: string) { if (!x) return; // після return TypeScript знає, що нижче x точно string console.log(x.toUpperCase()); // OK } ``` TS автоматично виключає `undefined` після `if (!x) return`. --- ### 3. Щоб зручно працювати з union-типами Union-типи (`A | B | C`) - потужний інструмент, але без narrowing вони марні. ```javascript type Result = { ok: true; data: string } | { ok: false; error: Error }; function handle(result: Result) { if (result.ok) { console.log(result.data); // TS розуміє, що тут data є } else { console.log(result.error.message); // і тут error точно є } } ``` TypeScript "звужує" `Result` до конкретного варіанта залежно від перевірки. --- ### 4. Щоб не використовувати `as` і каст скрізь Без narrowing довелося б "підказувати" компілятору тип вручну: ```javascript if (typeof value === "string") { console.log((value as string).toUpperCase()); // зайвий cast } ``` TypeScript робить це **автоматично**: ```javascript if (typeof value === "string") { console.log(value.toUpperCase()); // без кастів } ``` Код стає **чистішим, коротшим і безпечнішим**. --- ### 5. Щоб реалізовувати "discriminated unions" Це просунута форма звуження (за дискримінатором), яка дозволяє описувати складні стани: ```javascript type State = | { status: "loading" } | { status: "success"; data: string } | { status: "error"; message: string }; function render(state: State) { switch (state.status) { case "loading": return "Loading..."; case "success": return state.data; // TS знає, що тут є data case "error": return state.message; // тут - message } } ``` TS звужує тип за значенням поля `status`. Це ключ до створення **строго типізованих кінцевих автоматів і state machine-патернів**. --- ### 6. Щоб покращувати автодоповнення та інтелект IDE Звуження напряму впливає на те, **наскільки "розумно"** працює підказка IDE. Наприклад: ```javascript function demo(x: string | number) { if (typeof x === "string") { x. // автодоповнення покаже лише string-методи } } ``` У вас **автоматично підказуються лише допустимі властивості**, а не все підряд. --- ## Без narrowing TypeScript був би "дурним" Без нього: - типи були б занадто загальними (`any`, `unknown`, `string | number | ...`); - IDE не знала б, які методи доступні; - код став би небезпечним (помилки на етапі виконання); - довелося б скрізь писати `as Type`. TypeScript фактично був би просто "JS з анотаціями", а не розумним статичним аналізатором. --- ## Підсумок | Мета | Що дає звуження | |---|---| | Безпека | Захист від звернень до неіснуючих властивостей | | Зручність | Не потрібно явно кастити типи | | Розумні підказки | IDE пропонує лише допустимі методи | | Контроль потоку | TS розуміє, що залишається після `if`, `return`, `throw` | | Expressive typing | Дозволяє створювати "дискриміновані об'єднання" | | Чистота коду | Менше `as`, менше бойлерплейту, більше точності | --- **Простіше кажучи:** > Звуження типів потрібне, щоб TypeScript міг "думати як людина" - > розуміти, який тип насправді в кожному конкретному рядку коду.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.