TypeScript with React

TypeScript adds static checking to React applications. Type component props, state models, event handlers, API responses, and reusable hooks. Avoid using any as a shortcut because it removes the compiler's ability to detect mismatches.

Prefer discriminated unions for UI states that have mutually exclusive shapes. This models loading, success, and error states more accurately than a collection of optional fields.

Use unknown for untrusted values and narrow them before use. Runtime validation is still required for data arriving from APIs because TypeScript types disappear at runtime.

Discriminated async state
type RequestState<T> =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; message: string };

function Message({ state }: { state: RequestState<string> }) {
  if (state.status === "loading") return <p>Loading...</p>;
  if (state.status === "error") return <p>{state.message}</p>;
  if (state.status === "success") return <p>{state.data}</p>;
  return <p>Start</p>;
}
💡 The status field lets TypeScript narrow the data shape safely.
Key Takeaways
  • Types should model real UI states.
  • Do not confuse compile-time types with runtime validation.
  • Prefer precise types over any.