TypeScript2026-02-14 ยท 4 min
Types as guardrails, not decoration
A type that mirrors your object shape adds nothing. A type that makes the wrong state unrepresentable pays for itself.
Mirror types do nothing
type Request = { loading: boolean; data?: User; error?: string };This allows loading: true with both data and error set. The compiler is happy; your UI is not.
Make illegal states unrepresentable
type Request =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: User }
| { status: 'error'; error: string };Now the switch statement is exhaustive and the impossible branch never ships.
Small habits that compound
- Prefer unions over optional flags.
- Use
as constfor literal config, then derive types from it. - Reserve
anyfor boundaries you immediately validate.