En diskriminerad (märkt) union är en union av objekttyper som alla delar ett gemensamt literalt fält — diskriminanten — som kompilatorn använder för att skilja varianterna åt och göra säker inskränkning.
=
| { : }
| { : ; : }
| { : ; : };
En diskriminerad (märkt) union är en union av objekttyper som alla delar ett gemensamt literalt fält — diskriminanten — som kompilatorn använder för att skilja varianterna åt och göra säker inskränkning.
=
| { : }
| { : ; : }
| { : ; : };
Varje medlem har ett status-literal. Om du kontrollerar det inskränks det till exakt en variant, vilket låser upp den variantens fält:
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
}
}
Om du försöker få åtkomst till r.data i loading-fallet är det ett kompileringsfel — typsystemet gör ogiltiga kombinationer omöjliga att representera.
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;
}
}
never-tilldelningen tvingar dig att hantera varje fall — lägg till en ny status och kompilatorn pekar på varje switch som behöver uppdateras.
Diskriminerade unioner är det idiomatiska sättet att modellera tillstånd (loading/success/error), events/actions (Redux reducers) och vilken "en av flera former"-data som helst.
De gör illegala tillstånd omöjliga och, med never-tricket, ger dig kompileringstidskontroll för uttömmande — en enorm säkerhetsvins jämfört med löst boolean/valfri fältmodellering.