Какво представляват генериците и как да ги използваме с TypeScript?

Generics са мощен инструмент в програмирането, който ви помага да предотвратите повтарящ се код. Те предлагат начин за създаване на функции за многократна употреба, които могат да работят с различни типове, а не с един единствен.

В тази статия ще представя генерични кодове в TypeScript. Ще разгледаме как могат да се използват с някои основни примери.

Ако не сте запознати с TypeScript, вижте статията по-долу, за да започнете.



Как да използвам Generics в TypeScript?

За да започнем с генеричните продукти, ще разгледаме най-основния пример, както е показано в документацията на TypeScript.

function identity(arg: number): number {
  return arg;
}
function identity(arg: string): string {
  return arg;
}

Тук имаме две функции. Единият приема число като аргумент и връща числото; другият приема низ като аргумент и връща низа.

Следвайки правилата на TypeScript, в първата функция identity мога да предам само число като аргумент. Ако се опитам да предам низ или друг тип, ще получим грешка. Във втората функция identity мога да предам само низ като аргумент. Ако се опитам да предам число или друг тип, ще получим грешка.

Можем да намалим повтаряемия код, като вземем тези две функции и ги превърнем в една. Един от начините да направите това е да използвате типа any. Ако дадем на аргумента и върнатата стойност на функцията identity тип any, можем да предадем всяка стойност, която пожелаем.

function identity(arg: any): any {
  return arg;
}

Сега можем да предадем или число, или низ към тази функция. Този подход обаче обезсмисля причината да използвате TypeScript на първо място. Използвайки типа any, губим информацията за типа на аргумента.

По-добър подход би бил да добавите променлива тип към функцията. Тук влизат в действие генеричните лекарства. Можем да добавим тип променлива към функцията, като предадем тип в <> скоби.

function identity<Type>(arg: Type): Type {
  return arg;
}

Тук добавяме променлива тип с име Type. Променливата тип се използва като тип аргумент и тип връщана стойност.

Сега все още можем да предадем число или низ като аргумент. Този път можем изрично да кажем на TypeScript типа, който ще се използва като тип на аргумента и връщаната стойност.

Или можем да използваме извод за аргумент тип, за да накараме TypeScript да зададе типа автоматично.

Как да създадете общо ограничение?

Ами ако имам нужда от достъп до свойство или метод на аргумента? Например, ако искам да получа достъп до свойството length на аргумента.

function identity<Type>(arg: Type): Type {
  console.log(arg.length)
  return arg;
}

За съжаление, TypeScript ще се оплаче от това.

Понастоящем аргументът ще бъде какъвто и да е тип, който предавате в общата функция. Това означава, че може да бъде низ, число или друг тип. Ако аргументът е число, свойството length няма да съществува. Ето защо получаваме грешка.

В тази ситуация можем да създадем интерфейс, който ще опише ограничението. Тук можем да кажем, че аргументът трябва да има свойство length, което е number.

interface ArgWithLength {
  length: number;
}

След това ще разширим типа в нашата функция, за да включим това ограничение.

function identity<Type extends ArgWithLength>(arg: Type): Type {
  console.log(arg.length)
  return arg;
}

След като използваме ключовата дума extends, ще видим, че грешката е изчезнала. Това е така, защото добавяме ограничението, че какъвто и аргумент да подадем във функцията, трябва да има свойството length.

Ако се опитам да предам число във функцията identity, ще получим TypeScript грешка. Това е така, защото числото няма свойство length. Въпреки това, ако подадем низ или масив, ще бъде добре. Това е така, защото и двамата имат свойство length.

Заключение

Благодаря за четенето! Надявам се, че тази статия ви е била полезна, за да започнете с генеричните кодове в TypeScript. Когато за първи път започнах да научавам за генеричните лекарства, те изглеждаха наистина сложни. Но след известно време, за да го научите, те всъщност не са толкова трудни за разбиране.

Възможността да използвате генерични продукти е мощен инструмент, който може да ви помогне да пишете функции за многократна употреба и да предотвратите повтарящ се код.

Ако искате да продължите да научавате повече за TypeScript, вижте статията по-долу.