Модульні уроки (2/2)
Фундаментальні дженерики
Generics (загальне програмування) є однією з найпотужніших функцій TypeScript. Вони дозволяють писати гнучкі багаторазові компоненти, функції та інтерфейси, які можуть працювати з різними типами даних, зберігаючи максимальну безпеку типів і уникаючи використання any.
Загальні функції
Подумайте про загальне як про змінну для типів. Давайте розглянемо функцію, яка повертає значення, передане їй як аргумент:
function identity<T>(arg: T): T {
return arg;
}Літера T (скорочення від Type) є покажчиком місця заповнення для типу. Коли ми викликаємо identity, TypeScript фіксує тип переданого аргументу та автоматично встановлює T на цей тип:
const str = identity<string>('Hello'); // T is string
const num = identity(42); // T is number (automatically inferred!)Загальні інтерфейси та псевдоніми
Генерики також можна застосовувати до інтерфейсів і псевдонімів типів для визначення загальних контейнерів або структур даних:
interface Box<T> {
content: T;
}
const stringBox: Box<string> = { content: 'TypeScript' };
const numberBox: Box<number> = { content: 42 };Кілька параметрів типу
Ми можемо визначити функції або типи, які використовують кілька змінних типу (наприклад, T та U):
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}Загальні обмеження
Іноді ми хочемо обмежити типи, прийнятні дженеріком. Ми можемо використовувати ключове слово extends, щоб додати обмеження.
Наприклад, якщо ми хочемо, щоб загальний тип завжди мав властивість length (наприклад, рядки або масиви):
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length); // Safe! We know arg has 'length'
}
logLength('Hello'); // Valid
logLength([1, 2, 3]); // Valid
// logLength(42); // Error: number does not have a length property!Спробуйте самі
Вправа 1: Загальна функція тотожності
Завершіть функцію загальної ідентифікації, щоб вона приймала параметр значення загального типу T і повертала його без змін.
Показати підказку
Повернутий тип має бути таким же загальним типом T, що й параметр.
Рішення доступне після 3 спроб
Вправа 2: Загальна обгортка коробки
Визначте загальний інтерфейс під назвою Box, який приймає параметр типу T і має одну властивість під назвою content типу T.
Показати підказку
Використовуйте інтерфейс Box<T> { content: T; } синтаксис.
Рішення доступне після 3 спроб
Вправа 3: Загальне обмеження
Напишіть загальну функцію під назвою getLength, яка приймає параметр arg. arg повинен бути обмежений інтерфейсом, який має властивість length (число). Функція має повертати arg.length.
Показати підказку
Оголошіть функцію як getLength<T extends HasLength>(arg: T): число та поверніть arg.length.
Рішення доступне після 3 спроб
Вправа 4: родова пара
Визначте загальний інтерфейс Pair<T, U> із двома властивостями: перша — типу T, а друга — типу U. Далі створіть загальну функцію makePair, яка приймає перше (типу T) і друге (типу U) і повертає об’єкт, що реалізує Pair<T, U>.
Показати підказку
Використовуйте синтаксис для двох загальних параметрів Pair<T, U> і відповідно визначте makePair.
Рішення доступне після 3 спроб