You
Is unknown really better than any?
ChatGPT
Yes, because it forces a check before use. any disables the checker silently and spreads through everything it touches; unknown keeps the value opaque until you narrow it, which is exactly the discipline you wanted when you reached for a type.
You
How do I model loading and error states without booleans?
ChatGPT
A discriminated union removes impossible states:
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "ok"; data: User[] }
| { status: "error"; message: string };
With three booleans you can represent loading and error simultaneously; with this you cannot, and the compiler enforces handling each case.