Discriminated Unions
Normal Union
type State = {
status: "loading" | "success" | "error";
error?: Error;
data?: Array<{ id: number; name: string }>;
};
Example 1 - These are type-safe:
const state1: State = {
status: "loading",
};
const state2: State = {
status: "success",
data: [{ id: 1, name: "Jane" }, { id: 2, name: "John" }],
};
const state3: State = {
status: "error",
error: new Error("The task failed successfully"),
};
Example 2 - These are also type-safe but logically incorrect:
// The data has been fetched, but the status is still "loading"
const state4: State = {
status: "loading",
data: [{ id: 1, name: "Jane" }, { id: 2, name: "John" }],
};
// The status is "success", but there is an error present
const state5: State = {
status: "success",
error: new Error("The task failed successfully"),
};
// The status is "error", but there is no error object
const state6: State = {
status: "error",
};
Discriminated Union
Invalid combinations like in Example 2 are now caught by the type system:
type State =
| { status: "loading" }
| { status: "success"; data: Array<{ id: number; name: string }> }
| { status: "error"; error: Error };