Generics di TypeScript: come creare modelli di codice riutilizzabili
I generics di TypeScript servono a generare codice riutilizzabile e sicuro rispetto al tipo. Questo sistema può essere applicato a funzioni, classi, interfacce e tipi, ma non solo.
Che cosa sono i generics di TypeScript?
In quasi ogni linguaggio di programmazione sono disponibili strumenti che permettono agli utenti di creare modelli di codice da riutilizzare nel corso della programmazione o in altri progetti. L’obiettivo non è soltanto risparmiare tempo, ma anche creare codice sicuro che si possa integrare perfettamente in nuovi ambienti. In questo modo è possibile scrivere e replicare diversi componenti, funzioni e strutture dati complete senza perdere la loro sicurezza rispetto al tipo. In TypeScript questi compiti sono affidati ai cosiddetti generics. In tal modo è possibile trasmettere i tipi, sotto forma di parametri, ad altri tipi, funzioni o altre strutture dati.
- Massima sicurezza dei tuoi dati
- Strumenti di collaborazione per lavorare in team
- Aggiornamenti automatici
Esempio di sintassi e funzionamento
La base per lavorare con i generics di TypeScript sono le variabili generiche. Queste fungono da segnaposti per indicare il tipo di dati da dichiarare in un secondo momento. All’interno del codice sono contrassegnate con una lettera maiuscola a piacere. Durante la creazione del codice, queste variabili sono scritte tra parentesi angolari. Assegnando loro il nome del tipo vero e proprio, la funzione TypeScript, l’interfaccia o la classe TypeScript desiderate prendono il posto del segnaposto. Questo segnaposto è detto anche parametro Type. È anche possibile inserire diversi parametri Type all’interno delle parentesi. Quello che segue è un semplice esempio per conoscere la sintassi dei generics di TypeScript:
function FunzioneEsempio <T>(parameter1: T): void {
    console.log(`Il tipo di dati del parametro ${parameter1} è: ${typeof parameter1}`)
}Qui utilizziamo il nome della funzione (“FunzioneEsempio”) per definire la variabile generica “T”. Nel codice seguente dichiariamo questa variabile come stringa:
FunzioneEsempio<string>("Qui è presente una stringa.");Se ora assegniamo il valore del parametro string alla funzione, otteniamo il seguente risultato:
Il tipo di dati del parametro Qui è presente una stringa. è: stringI generics di TypeScript con due variabili
I generics di TypeScript funzionano in modo simile anche quando si utilizzano due o più variabili generiche come segnaposti. Nell’esempio seguente definiamo le variabili “T” e “U” come tipi per i parametri “parameter1” e “parameter2“. I due parametri sono separati da una virgola:
function FunzioneEsempio<T, U>(parameter1: T, parameter2: U): string {
    return JSON.stringify({parameter1, parameter2});
}Ora assegniamo i tipi di dati e i valori ai due segnaposti. In questo caso utilizziamo i tipi di dati number e string nonché i valori “11” e “giocatori”. Il codice per farlo è il seguente:
const str = FunzioneEsempio<number, string>(11, "giocatori");
console.log(str);Esempi di classi riproducibili
Puoi utilizzare i generics di TypeScript anche per creare classi riproducibili. Nell’esempio seguente utilizziamo i generics per chiedere al sistema di restituire un numero. Il codice per farlo è il seguente:
class ValoreNumerico<T> {
    private _value: T | undefined;
    constructor(private name: string) {}
    public setValue(value: T) {
        this._value = value;
    }
    public getValue(): T | undefined {
        return this._value;
    }
    public toString(): string {
        return `${this.name}: ${this._value}`;
    }
}
let value = new ValoreNumerico<number>('mioNumero');
value.setValue(11);
console.log(value.toString());In questo modo otteniamo il seguente output:
mioNumero: 11Naturalmente questo principio funziona anche con altri tipi di dati e con più variabili generiche. L’esempio seguente lo dimostra:
class ClasseEsempio<T, U> {
nome: T;
cognome: U;
constructor(nome: T, cognome: U) {
	this.nome = nome;
	this.cognome = cognome;
	}
}A questo punto, assegniamo il tipo di dati String e i valori previsti a ciascuna variabile:
const person1 = new ClasseEsempio<string, string>("Giulia", "Rossi");
console.log(`${person1.nome} ${person1.cognome}`)Questa volta otteniamo il seguente risultato:
Giulia RossiSe desideri combinare diversi tipi di dati, procedi come nell’esempio seguente:
class ClasseEsempio<T, U> {
numero: T;
parola: U;
constructor(numero: T, parola: U) {
	this.numero = numero;
	this.parola = parola;
	}
}Ai segnaposti vengono ora assegnati i tipi di dati number e string, nonché i relativi valori:
const combinazione = new ClasseEsempio<number, string>(11, "giocatori");
console.log(`${combinazione.numero} ${combinazione.parola}`);Il risultato è il seguente:
11 giocatoriUtilizzo con interfacce
Anche per le interfacce è possibile e addirittura consigliato utilizzare i generics di TypeScript. La procedura è simile alla dichiarazione di una classe:
interface Interfaccia<T> {
	valore: T;
}Quindi implementiamo l’interfaccia nella classe “ClasseEsempio”. A tal fine assegniamo il tipo di dati string alla variabile “T”:
class ClasseEsempio implements Interfaccia<string> {
	valore: string = "Questo è un esempio con un'interfaccia";
}
const output = new ClasseEsempio();
console.log(output.valore)Il nostro output è quindi simile al seguente:
Questo è un esempio con un'interfacciaCreazione di array generici
È possibile utilizzare i generics di TypeScript anche per gli array di TypeScript. A seguire trovi un semplice esempio di codice che utilizza la funzione reverse per invertire l’ordine dei numeri in un array:
function reverse<T>(array: T[]): T[] {
    return array.reverse();
}
let numeri: number[] = [10, 7, 6, 13, 9];
let NuovoOrdine: number[] = reverse(numeri);
console.log(NuovoOrdine);Otteniamo il seguente risultato:
[9, 13, 6, 7, 10]Generics di TypeScript per tipi condizionali
Infine, ti mostriamo anche come utilizzare i tipi che presentano una condizione per mezzo dei generics di TypeScript. Il risultato cambia a seconda che una condizione sia soddisfatta o meno. Nell’esempio seguente, questo requisito deve essere il tipo di dati string. Il relativo codice è il seguente:
type QuestaèunaStringa<T> = T extends string ? true : false;
type A = "esempio";
type B = {
	nome: string;
};
type PrimoRisultato = QuestaèunaStringa<A>;
type SecondoRisultato = QuestaèunaStringa<B>;In type A si trova quindi la stringa “esempio”, mentre con type B è indicato un oggetto con una proprietà “nome” e il tipo di dati string. Indichiamo quindi questi due tipi come “PrimoRisultato” e “SecondoRisultato”. Se poi andiamo a verificare questi due tipi, troviamo che “PrimoRisultato” riceve come stringa il valore true, mentre “SecondoRisultato” rimane false.
Deployment diretti tramite GitHub: Deploy Now di IONOS è la scelta migliore per siti web e app grazie al rilevamento automatico dei framework, alla velocità di configurazione e all’ottima scalabilità. Scegli il piano più adatto per il tuo progetto.

