Ти вже користуєшся generics — Array<T>, Promise<T>. Цей урок про один зсув: навчитися писати їх. Уся магія — в одній ідеї.
<T> — це параметр. Для типів.Звичайна функція приймає значення в дужках ( ). Generic-функція додатково приймає тип у кутових дужках < >. Хто його передає? Майже завжди — не ти вручну, а викликач, автоматично, з аргументів.
T — це просто ім'я-заповнювач для типу, який стане відомий лише в момент виклику. Він зв'язує вхід із виходом.
any?Спокуса: «нехай приймає будь-що — поставлю any». Але any стирає типову інформацію — і TS перестає тобі допомагати:
// any: TS більше не знає, що повернулось function firstAny(arr: any[]): any { return arr[0]; } const a = firstAny([1, 2]); a.toUpperCase(); // ⚠️ компілюється, але впаде в рантаймі (number.toUpperCase) // generic: тип зберігається, помилку видно одразу function first<T>(arr: T[]): T { return arr[0]; } const b = first([1, 2]); // b: number b.toUpperCase(); // ❌ TS-помилка ще до запуску — саме те, що треба
any розриває цей зв'язок назавжди.
function first<T>(arr: T[]): T { return arr[0]; } // ▲оголошуємо ▲вживаємо ▲вживаємо //треба ОГОЛОСИТИ один раз перед (...), далі вживай як звичайний тип.
T, Item, Element — однаково. T — лише конвенція (Type). Головне — оголосити в < > перед використанням.
Дано function first<T>(arr: T[]): T. Для кожного виклику обери, який тип буде у результату. Фідбек — одразу.
<T>, чого не дає any?T у виклику first([1, 2])?Відкрий TS Playground, встав це і наведи мишею на r1, r2, r3 — побачиш виведені типи:
function last<T>(arr: T[]): T { return arr[arr.length - 1]; } const r1 = last([10, 20, 30]); // наведи: number const r2 = last(["a", "b"]); // наведи: string const r3 = last([true, false]); // наведи: boolean
Одна функція — три різні типи, нуль any, нуль дублювання. Оце і є сила generics.
Готовий копати далі? Спитай мене прямо в чаті. Наприклад:
extends-constraints — наступний урок.»