I generici sono una caratteristica fondamentale di TypeScript che consente di scrivere funzioni e classi che lavorano con un insieme di tipi di dati in modo generico, piuttosto che essere vincolati a un tipo di dato specifico.
Le funzioni e le classi generiche possono essere utilizzate per aumentare la riusabilità del codice e rendere le applicazioni più flessibili. Ad esempio, una funzione generica per l’inversione di una stringa può essere utilizzata con qualsiasi tipo di stringa, senza la necessità di scrivere una funzione separata per ogni tipo di stringa:
function reverse<T>(input: T): T {
return input.split('').reverse().join('');
}
console.log(reverse('Hello world')); // "dlrow olleH"
console.log(reverse([1, 2, 3, 4])); // [4, 3, 2, 1]
console.log(reverse({ name: 'John', age: 30 })); // TypeError: input.split is not a function
In questo esempio, abbiamo definito una funzione reverse
generica che accetta un parametro di tipo T
e restituisce lo stesso tipo di dati. La funzione utilizza il metodo split
, reverse
, e join
per invertire la stringa di input.
In questo caso, abbiamo chiamato la funzione reverse
con una stringa, un array di numeri e un oggetto, e TypeScript ha infatti rilevato un errore nel terzo caso, poiché l’oggetto non ha un metodo split
.
Inoltre, i generici possono essere utilizzati anche con le classi, ad esempio per creare una classe Stack
generica che può essere utilizzata per gestire una pila di qualsiasi tipo di dati:
class Stack<T> {
private items: T[] = [];
push(item: T) {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.pop()); // 3
console.log(stack.peek()); // 2
console.log(stack.isEmpty()); // false
const stringStack = new Stack<string>();
stringStack.push('Hello');
stringStack.push('World');
console.log(stringStack.pop()); // "World"
console.log(stringStack.peek()); // "Hello"
console.log(stringStack.isEmpty()); // false