Что такое Generic в TypeScript
Generic в TypeScript — это возможность создавать универсальные компоненты и функции, которые могут работать с любыми типами данных, при этом сохраняют типовую безопасность. С помощью Generic можно создать функции, классы и интерфейсы, которые могут работать с разными типами, не теряя при этом строгой типизации.
Зачем нужны Generic?
-
Гибкость: Generic позволяют создавать универсальные функции и классы, которые могут работать с различными типами данных. Это дает возможность избежать дублирования кода, обеспечивая при этом типовую безопасность.
-
Повторное использование кода: Generic позволяют писать код, который можно многократно использовать для разных типов, улучшая читаемость и уменьшая количество повторений.
-
Типовая безопасность: Использование Generic обеспечивает проверку типов в момент компиляции, что помогает избежать ошибок, связанных с неправильным использованием типов.
Generic в функциях
С помощью Generic можно создавать функции, которые принимают параметры разных типов, при этом TypeScript будет отслеживать типы данных.
Пример:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("Hello");
let output2 = identity<number>(100);
В этом примере T — это обобщенный тип, который будет автоматически определяться на основе типа переданного аргумента. Функция identity возвращает значение того же типа, что и переданному аргументу.
Generic с массивами
Мы можем создавать функции для работы с массивами, где элементы массива могут быть любого типа.
function logArray<T>(arr: T[]): void {
arr.forEach(item => console.log(item));
}
logArray([1, 2, 3]); // number[]
logArray(["a", "b", "c"]); // string[]
В этом примере функция logArray принимает массив с любыми типами данных и выводит его элементы в консоль.
Generic в интерфейсах
Generic могут быть использованы в интерфейсах для создания более гибких и универсальных структур данных.
interface Box<T> {
value: T;
}
let box1: Box<string> = { value: "Hello" };
let box2: Box<number> = { value: 100 };
В этом примере Box
является универсальным интерфейсом, который может работать с любыми типами, и тип данных будет задаваться при создании экземпляра интерфейса.
Generic в классах
Generic также можно использовать в классах для создания универсальных классов.
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
const box1 = new Box<string>("Hello");
const box2 = new Box<number>(100);
console.log(box1.getValue()); // "Hello"
console.log(box2.getValue()); // 100
В этом примере класс Box
использует Generic для работы с разными типами данных, что позволяет создавать экземпляры с различными типами значений.
Ограничения Generic
Можно ограничить типы, которые могут быть использованы в Generic, с помощью ограничений. Например, вы можете указать, что параметр типа должен быть объектом с определенным свойством.
function logLength<T extends { length: number }>(arg: T): void {
console.log(arg.length);
}
logLength("Hello"); // 5
logLength([1, 2, 3]); // 3
Здесь T
extends { length: number }
указывает, что T
должен быть объектом с свойством length, таким образом, функция может работать только с такими типами, как строками или массивами.