HeadlinesBriefing favicon HeadlinesBriefing.com

TypeScript Type-Safe REST API Client

DEV Community •
×

TypeScript developers often lose type safety at API boundaries when calling response.json(), which returns an 'any' type and allows bugs to slip into production. This article presents a solution using discriminated unions to maintain type safety throughout the entire request and response cycle. By structuring API responses with a discriminator field, developers can ensure compile-time checks instead of relying on runtime validation.

The architecture centers on three core components: discriminated union types for response handling, a generic store class that works with any data model, and type guards for automatic type narrowing. Instead of throwing exceptions, the client returns a union type—either a success or error object—allowing TypeScript to infer the correct shape based on a 'type' field. This approach eliminates messy try-catch blocks that obscure type information.

A generic constraint like `T extends { id: number | string }` ensures CRUD operations remain safe across different models. The implementation uses status code conventions where 0 indicates network failures, distinguishing them from HTTP errors. Type guards such as `isSuccessResponse()` and `isErrorResponse()` enable clean, readable control flow without explicit type assertions, making error handling exhaustive and maintainable.

While this pattern offers zero dependencies and full compile-time safety, it lacks advanced features like caching or retry logic found in libraries like Axios or TanStack Query. For small to medium projects, this approach provides a lightweight foundation. Future enhancements could include request cancellation, optimistic updates, and React hook integrations, making it a robust starting point for scalable, type-safe API communication.