I tipi di intersezione (&, intersection types) consentono di combinare più tipi in uno, possedendo tutte le proprietà dei tipi uniti.
type Person = { name: string }; type Worker = { job: string }; type WorkingPerson = Person & Worker; // { name: string; job: string } const wp: WorkingPerson = { name: "Leo", job: "Dev" };
Questo è utile nella composizione di contratti espandibili e nella costruzione di tipi complessi a partire da primitivi.
Tuttavia, se si sovrappongono tipi incompatibili (ad esempio, type A = { foo: string } e type B = { foo: number }), si ottiene un tipo che non può essere inizializzato.
type A = { foo: string }; type B = { foo: number }; type C = A & B; // C = { foo: never }
Cosa succede se si sovrappongono due tipi che hanno una proprietà identica con tipi di dati incompatibili?
Risposta: Si ottiene una proprietà con tipo never, poiché un valore non può essere contemporaneamente sia una stringa che un numero. Questo tipo non può essere implementato validamente.
type T1 = { id: string }; type T2 = { id: number }; type T3 = T1 & T2; // { id: never }
Storia
Nel progetto si sovrapponevano tipi di diverse librerie, senza notare che avevano proprietà identiche con tipi diversi. Di conseguenza si otteneva un tipo "impossibile" (never) che portava all'impossibilità di creare un oggetto valido da inviare all'API.
Storia
Un sviluppatore doveva "unire" tipi DTO e entità di dominio. Nell'intersezione c'erano due proprietà incompatibili, e tentare di utilizzare il tipo risultante generava errori di compilazione ambigui. Lo sviluppatore ha speso tempo in debug prima di capire il motivo.
Storia
In uno dei microservizi era stato dichiarato un tipo di intersezione per descrivere il corpo della richiesta. A causa di una modifica dell'API, una delle proprietà ha ottenuto un altro tipo, e i nuovi cambiamenti non hanno immediatamente portato a un errore di compilazione: i problemi sono sorti solo al runtime dopo il deploy.