Skip to content

TypeScript refresher

Prefer domain types

Use literal unions for closed states and discriminated unions for actions and async state. Avoid any; validate unknown at trust boundaries.

interface Ready<T> { status: 'ready'; data: T }
interface Failed { status: 'failed'; message: string }
type LoadState<T> = { status: 'idle' | 'loading' } | Ready<T> | Failed

React guidance

  • Infer JSX return types unless an exported contract benefits from annotation.
  • Type props as read-only data and explicit callbacks.
  • Use FormEvent, ChangeEvent, and element-specific targets deliberately.
  • Do not use non-null assertions for values that can genuinely be absent.
  • Exhaustively switch discriminated actions and states.

Types prove static relationships, not payload validity, authorization, accessibility, or runtime success.