Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Виведення generic-типу». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Type inference** для generics - це механізм, за яким TypeScript сам аналізує передані аргументи функції і підставляє конкретний тип замість `T`, тож не потрібно явно писати `<string>`, `<number>` тощо. **Ключове:** якщо TypeScript не може вивести тип з аргументів (наприклад, з `null` чи `undefined`), тип потрібно вказати явно.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке type inference в контексті generics Коли ви викликаєте функцію з generic-параметром, TypeScript **аналізує передані аргументи** і **сам підставляє тип** замість `T` (або інших параметрів). Тобто вам не потрібно явно писати `<string>`, `<number>` тощо - компілятор робить це автоматично. ### Приклад 1: базове виведення типу ```javascript function identity<T>(value: T): T { return value; } const a = identity("Hello"); // T = string const b = identity(42); // T = number ``` TypeScript бачить, що аргумент `"Hello"` має тип `string`, і підставляє `T = string` автоматично. ### Приклад 2: виведення типу з кількох аргументів ```javascript function merge<T, U>(a: T, b: U): T & U { return Object.assign({}, a, b); } const result = merge({ name: "Tim" }, { age: 25 }); // TypeScript виводить T = { name: string }, U = { age: number } // Результат має тип { name: string; age: number } ``` Тут `T` і `U` виведені **по кожному аргументу окремо**. TypeScript об’єднує їх через `&`. ### Приклад 3: виведення з контексту (contextual inference) ```javascript function wrap<T>(value: T): { data: T } { return { data: value }; } const wrapped = wrap({ id: 1, name: "Tim" }); // T = { id: number; name: string } ``` TypeScript «бачить» структуру переданого об’єкта і виводить точний тип. ### Приклад 4: часткове виведення (partial inference) ```javascript function pair<T, U = string>(first: T, second?: U): [T, U] { return [first, second as U]; } const p1 = pair(1); // T = number, U = string (типово) const p2 = pair(true, false); // T = boolean, U = boolean ``` Можна задати **тип за умовчанням** для generic-параметра - тоді він використовується, якщо TypeScript не зміг вивести тип з аргументів. ### Приклад 5: виведення типу при поверненні функції ```javascript function makeArray<T>(item: T, times: number): T[] { return Array(times).fill(item); } const arr = makeArray(5, 3); // T = number → number[] ``` Тип `T` виведений з першого аргументу `item`. ### Приклад 6: коли виведення не працює ```javascript function logValue<T>(value: T): void { console.log(value); } logValue(null); // T не може бути виведений точно logValue(undefined); // те саме ``` У таких випадках потрібно вказати тип явно: ```javascript logValue<string | null>(null); ``` ## Як працює виведення під капотом TypeScript застосовує кілька стратегій: 1. **From arguments → to type parameters** - аналіз аргументів та їхніх типів. 2. **From return type** - якщо тип результату можна обчислити. 3. **Contextual typing** - аналіз контексту, де використовується функція. Приклад контекстного виведення: ```javascript const handler = <T>(value: T) => console.log(value); ["a", "b", "c"].forEach(handler); // TypeScript розуміє, що T = string ``` ## Підсумок | Що робить TS | Приклад | Результат | |---|---|---| | Виводить тип з аргументу | `identity(42)` | `T = number` | | Виводить тип з кількох аргументів | `merge({a: 1}, {b: 2})` | `T = {a: number}, U = {b: number}` | | Застосовує тип за умовчанням | `pair(1)` | `U = string` | | Контекстне виведення | `["x"].forEach(handler)` | `T = string` | | Не може вивести тип | `logValue(null)` | потрібно вказати явно |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.