Skip to main content
Back to All Technical Guides
Web DevelopmentJuly 15, 20267 min readGerardo B. Galvez IIGerardo B. Galvez II

Pragmatic TypeScript Patterns for Reliable Web Applications

"Actionable techniques for typing async state, handling API boundary validation, and avoiding excessive type complexity."

#TypeScript#Best Practices#React

TypeScript is most effective when it makes bugs obvious at compile time without making code unreadable. Here are practical patterns for maintaining clean, robust TypeScript web applications.

1. Discriminated Unions for Async State

Avoid using separate boolean flags like isLoading, isError, and data which can represent impossible states. Instead, use a single discriminated union type.

Code Snippet (typescript)
type AsyncData<T> =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; error: string };

function renderState<T>(state: AsyncData<T>) {
  switch (state.status) {
    case "idle": return null;
    case "loading": return <Spinner />;
    case "error": return <ErrorMessage message={state.error} />;
    case "success": return <DataView data={state.data} />;
  }
}

Conclusion & Key Takeaways

Focus TypeScript efforts on state boundaries and public API contracts to maximize reliability with minimal friction.