Вы устали писать повторяющийся код на TypeScript? Хотите повысить возможность повторного использования вашего кода, обеспечив при этом безопасность типов? Не смотрите дальше! В этой статье мы погрузимся в мир дженериков TypeScript. Обобщения позволяют нам писать гибкий и многократно используемый код, который работает с разными типами данных, не жертвуя безопасностью типов. Итак, давайте начнем и рассмотрим некоторые важные методы и приемы использования дженериков в TypeScript.
- Общие функции:
Один из основных способов использования дженериков — создание универсальных функций. Эти функции могут работать с несколькими типами данных, обеспечивая гибкость и возможность повторного использования. Вот пример:
function reverseArray<T>(array: T[]): T[] {
return array.reverse();
}
const numbers = [1, 2, 3, 4, 5];
const reversedNumbers = reverseArray(numbers); // [5, 4, 3, 2, 1]
const names = ["Alice", "Bob", "Charlie"];
const reversedNames = reverseArray(names); // ["Charlie", "Bob", "Alice"]
- Общие классы:
Обобщенные элементы также можно применять к классам, что позволяет нам создавать повторно используемые компоненты, работающие с различными типами данных. Рассмотрим следующий пример общего класса Stack:
class Stack<T> {
private elements: T[] = [];
push(element: T): void {
this.elements.push(element);
}
pop(): T | undefined {
return this.elements.pop();
}
}
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
numberStack.push(3);
console.log(numberStack.pop()); // 3
const stringStack = new Stack<string>();
stringStack.push("Hello");
stringStack.push("World");
console.log(stringStack.pop()); // "World"
- Общие интерфейсы:
Интерфейсы также можно сделать универсальными, что позволит нам определять многократно используемые контракты для разных типов данных. Вот пример:
interface Comparable<T> {
compareTo(other: T): number;
}
class Person implements Comparable<Person> {
constructor(public name: string) {}
compareTo(other: Person): number {
return this.name.localeCompare(other.name);
}
}
const alice = new Person("Alice");
const bob = new Person("Bob");
console.log(alice.compareTo(bob)); // -1
console.log(bob.compareTo(alice)); // 1
- Ограничения в универсальных шаблонах:
Иногда мы хотим ограничить типы, которые можно использовать с дженериками. Мы можем добиться этого, используя ограничения. Вот пример, демонстрирующий ограничение универсального типа объектом с определенным свойством:
function printProperty<T extends { name: string }>(obj: T): void {
console.log(obj.name);
}
const person = { name: "Alice", age: 25 };
const book = { title: "Harry Potter", author: "J.K. Rowling" };
printProperty(person); // "Alice"
printProperty(book); // Compilation error: Property 'name' is missing
В этой статье мы рассмотрели основы дженериков TypeScript и то, как они могут значительно улучшить возможность повторного использования кода и безопасность типов. Мы узнали об общих функциях, классах, интерфейсах и ограничениях. Используя дженерики, вы можете писать более гибкий и удобный в сопровождении код, который легко адаптируется к различным типам данных. Итак, начните использовать дженерики в своих проектах TypeScript и раскройте весь потенциал повторного использования кода.