Storia della questione:
Gli union types sono stati introdotti in TypeScript per descrivere variabili e parametri che possono assumere valori di diversi tipi. Questa possibilità ha notevolmente ampliato la flessibilità della tipizzazione rispetto ai linguaggi classici.
Problema:
In JavaScript, le funzioni e le variabili sono spesso multi-formato (ad esempio, accettano numeri o stringhe), il che complica la tipizzazione sicura. Senza gli union types, era necessario utilizzare any o duplicare il codice. Questo aumentava il numero di errori in produzione e complicava il lavoro in grandi team.
Soluzione:
Gli union types permettono di dichiarare una variabile che può essere di uno dei diversi tipi, garantendo operazioni corrette dopo un controllo. È inoltre supportato il narrowing del tipo, che aiuta il compilatore a "capire" con cosa ha a che fare.
Esempio di codice:
function formatId(id: number | string): string { if (typeof id === 'string') { return id.toUpperCase(); } return id.toString(); }
Caratteristiche chiave:
È possibile scrivere un'unione di oggetti con proprietà diverse e accedere a qualsiasi proprietà senza controllare?
No. Gli union types permettono di accedere solo a quelle proprietà e metodi che sono presenti in tutti i tipi. Per accedere a proprietà specifiche è necessario il narrowing del tipo.
Esempio di codice:
type Fish = { swim: () => void; }; type Bird = { fly: () => void; }; function move(animal: Fish | Bird) { // animal.swim(); // Errore senza narrowing if ('swim' in animal) { animal.swim(); // OK } }
Perché non tutti i metodi sono disponibili per l'union type string | number?
TypeScript consente negli union solo ciò che è presente in tutti i tipi inclusi. Per metodi specifici è necessario prima controllare il tipo reale.
Cosa succede se non si verifica il tipo in un'unione, ma si prova a chiamare un metodo specifico?
In tal caso si verificherà un errore di compilazione, poiché non è garantita la presenza del metodo. Funziona solo dopo il controllo di un tipo specifico.
È stato dato un tipo string | number a una variabile e senza controllo è stato fatto toUpperCase(). Di conseguenza, l'applicazione si interrompe con dati numerici.
Vantaggi:
Svantaggi:
Controlliamo il tipo prima di lavorare con il metodo:
if (typeof value === 'string') { return value.toUpperCase(); } else { return value.toString(); }
Vantaggi:
Svantaggi: