Generics TypeScript с примерами
Generics TypeScript — это мощная функция, которая позволяет создавать повторно используемые и типобезопасные компоненты. Generics предоставляют способ создания классов, функций и интерфейсов, которые работают с различными типами, сохраняя при этом сильную типобезопасность. Эта статья познакомит вас с generics и продемонстрирует, как их использовать, на практических примерах.
Понимание дженериков
Generics позволяют вам определить компонент с заполнителем для типа, с которым он работает. Вместо указания конкретного типа вы используете параметр generic-типа, который можно заменить любым типом при использовании компонента.
Базовый синтаксис
Базовый синтаксис для определения универсального типа — использование угловых скобок <>
с именем параметра типа. Вот простой пример:
function identity(value: T): T {
return value;
}
const stringIdentity = identity("Hello"); // string
const numberIdentity = identity(123); // number
В этом примере identity
— это общая функция, которая принимает параметр value
типа T
и возвращает значение того же типа. Параметр типа T
заменяется фактическим типом при вызове функции.
Дженерики с классами
Generics также можно использовать с классами для создания гибких и повторно используемых структур данных. Вот пример generic-класса:
class Box {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
const stringBox = new Box("TypeScript");
console.log(stringBox.getValue()); // Output: TypeScript
const numberBox = new Box(42);
console.log(numberBox.getValue()); // Output: 42
В этом примере класс Box
определен с параметром универсального типа T
. Класс имеет частное свойство value
типа T
и метод getValue
, который возвращает значение типа T
.
Дженерики с интерфейсами
Generics можно использовать с интерфейсами для создания гибких и типобезопасных интерфейсов. Вот пример:
interface Pair<T, U> {
first: T;
second: U;
}
const pair: Pair<string, number> = {
first: "Age",
second: 30
};
console.log(pair.first); // Output: Age
console.log(pair.second); // Output: 30
В этом примере интерфейс Pair
определен с двумя параметрами общего типа T
и U
. Интерфейс представляет собой пару значений с типами T
и U
соответственно.
Дженерики в функциях
Обобщения могут использоваться в функциях для обработки нескольких типов, сохраняя при этом безопасность типов. Вот пример обобщенной функции, которая работает с массивами:
function reverseArray(items: T[]): T[] {
return items.reverse();
}
const reversedStringArray = reverseArray(["one", "two", "three"]);
console.log(reversedStringArray); // Output: ["three", "two", "one"]
const reversedNumberArray = reverseArray([1, 2, 3]);
console.log(reversedNumberArray); // Output: [3, 2, 1]
В этом примере функция reverseArray
принимает массив типа T
и возвращает обратный массив того же типа. Параметр типа T
гарантирует, что функция работает с массивами любого типа, сохраняя безопасность типов.
Ограничения на дженерики
Иногда может потребоваться наложить ограничения на параметр универсального типа, чтобы гарантировать, что он имеет определенные свойства. Это делается с помощью ограничений:
function logLength(item: T): void {
console.log(item.length);
}
logLength("Hello, TypeScript"); // Output: 16
logLength([1, 2, 3]); // Output: 3
// logLength(123); // Error: number does not have a length property
В этом примере функция logLength
ограничена типами, имеющими свойство length
. Это позволяет функции принимать строки и массивы, но не числа или другие типы без свойства length
.
Заключение
Generics в TypeScript предоставляют мощный способ создания гибких и повторно используемых компонентов, сохраняя при этом сильную безопасность типов. Понимая и используя generics, вы можете писать более универсальный и адаптируемый код, улучшая общее качество и удобство обслуживания ваших приложений TypeScript.
Поэкспериментируйте с дженериками в своих проектах, чтобы увидеть их преимущества на практике и улучшить свои навыки программирования на TypeScript.