Una unión discriminada (etiquetada) es una unión de tipos de objeto que comparten un campo literal común — el discriminante — que el compilador usa para distinguir las variantes y acotar de forma segura.
=
| { : }
| { : ; : }
| { : ; : };
Una unión discriminada (etiquetada) es una unión de tipos de objeto que comparten un campo literal común — el discriminante — que el compilador usa para distinguir las variantes y acotar de forma segura.
=
| { : }
| { : ; : }
| { : ; : };
Cada miembro tiene un literal status. Comprobarlo acota a exactamente una variante, habilitando los campos de esa variante:
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
}
}
Si intentas acceder a r.data en el caso loading, es un error de compilación — el sistema de tipos hace que las combinaciones inválidas sean irrepresentables.
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;
}
}
La asignación a never te obliga a manejar cada caso — agrega un nuevo status y el compilador te señalará cada switch que necesita actualizarse.
Las uniones discriminadas son la forma idiomática de modelar estado (loading/success/error), eventos/acciones (reducers de Redux) y cualquier dato del tipo "una de varias formas".
Hacen que los estados ilegales sean imposibles y, con el truco de never, te dan exhaustividad en tiempo de compilación — una enorme ganancia de seguridad frente al modelado laxo con boolean o campos opcionales.