I Generics (tipi generici) permettono di scrivere codice universale che funziona con diversi tipi, mantenendo la rigorosa sicurezza dei tipi.
Sintassi di utilizzo:
function identity<T>(value: T): T { return value; } const x = identity<string>('test'); // T = string
Dove si applicano:
Esempio con restrizione di tipo:
function getFirst<T extends { length: number }>(arr: T): T { return arr[0]; }
Domanda: È obbligatorio specificare un tipo concreto quando si chiama una funzione con un parametro Generic?
Risposta:
Non è obbligatorio. TypeScript deduce da solo (inferisce) i tipi dai valori passati, se possibile. Ma a volte è comodo specificare esplicitamente, ad esempio, se il tipo non è chiaro dai valori o se ci sono più opzioni.
function identity<T>(value: T): T { return value; } identity(5); // T = number (auto) identity<string>('s'); // T = string (esplicito)
Storia
In un progetto di e-commerce è stato scritto un repository generico per diverse entità, ma si è dimenticata la restrizione di tipo. Di conseguenza, qualsiasi oggetto poteva entrare nel generico, e una volta è stata salvata un'entità con campi incompatibili. I tipi non hanno protetto da errori.
Storia
È stata passata una funzione generica a un array, aspettandosi di ricevere un array con un tipo di elementi. Ma la funzione restituiva any[], poiché il generico non era stato specificato esplicitamente e TypeScript non è riuscito a dedurre il tipo. L'errore è stato notato solo in produzione.
Storia
Uno sviluppatore principiante ha creato una classe generica senza restrizione di tipo, utilizzando un campo che non esisteva in tutti i tipi. Il compilatore non ha sollevato errori, ma accedendo a una proprietà inesistente, tutto il funzionalità si è rotta.