A diszkriminált (tagged) unió olyan típusok uniója, amelyek egy közös literális mező — a diszkriminátor — megosztanak, amit a fordító a variansok megkülönböztetésére és biztonságos szűkítésre használ.
=
| { : }
| { : ; : }
| { : ; : };
A diszkriminált (tagged) unió olyan típusok uniója, amelyek egy közös literális mező — a diszkriminátor — megosztanak, amit a fordító a variansok megkülönböztetésére és biztonságos szűkítésre használ.
=
| { : }
| { : ; : }
| { : ; : };
Minden tag rendelkezik literális status mezővel. Az ellenőrzés pontosan egy varianszra szűkít, feloldva az adott variánshoz tartozó mezőket:
function render(r: Result) {
switch (r.status) {
case "loading": return "...";
case "success": return r.data; // ✅ data exists only here
case "error": return r.message; // ✅ message exists only here
}
}
Ha megpróbálsz hozzáférni a r.data-hoz a loading esetben, fordítási hiba — a típusrendszer az érvénytelen kombinációkat nem reprezentálhatóvá teszi.
function render2(r: Result): string {
switch (r.status) {
case "loading": return "...";
case "success": return r.data;
case "error": return r.message;
default:
const _exhaustive: never = r; // ✅ if you add a variant and forget a case, this errors
return _exhaustive;
}
}
A never hozzárendelés arra kényszerít, hogy minden esetet kezelj — adj hozzá egy új státuszt és a fordító az összes olyan switch-re mutat, amelyet frissíteni kell.
A diszkriminált uniók az idiomatikus módja az állapot (töltés/siker/hiba), események/műveletek (Redux reducer), és bármely "több alakból egy" adat modellezésének.
Lehetetlen állapotokat tesznek, és a never trükkel fordítási idejű kimerültség-ellenőrzést biztosítanak — hatalmas biztonsági előny a laza boolean/optional mező modellezés helyett.