Instead of modelling state with several booleans:
type State = {
loading: boolean;
error: boolean;
data?: Product[];
};you can use a discriminated union:
type State =
| { status: "loading" }
| { status: "error"; message: string }
| { status: "success"; data: Product[] };The second version is much harder to misuse.
With multiple booleans, you can accidentally represent nonsense such as:
{
loading: true,
error: true,
data: [...]
}A discriminated union forces each state to have exactly the data that belongs to it. It also makes rendering logic cleaner because TypeScript can narrow the type based on status.