Typed API Hooks with React Query and TypeScript Generics
Leverage TypeScript generics to build reusable, type‑safe data‑fetching hooks with React Query, reducing boilerplate and catching API contract errors at compile time.
Insight
Creating a separate hook for every endpoint quickly becomes noisy, especially when the response shape varies. By defining a single generic useApi hook you let TypeScript infer the payload type from the function you pass in, while React Query still handles caching, retries, and background refetching. This pattern keeps your component code clean and guarantees that you only ever access fields that exist on the response.
Example
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
import { fetch } from 'expo-network';
// Generic hook
function useApi<T>(
key: string[],
url: string,
options?: UseQueryOptions<T>
) {
return useQuery<T>(key, async () => {
const res = await fetch(url);
return (await res.json()) as T;
}, options);
}
// Usage in a component
type User = { id: string; name: string; email: string };
const { data, isLoading } = useApi<User>(['user', id], `/api/users/${id}`);
Takeaway
Wrap your fetch logic in a single generic hook and let TypeScript do the heavy lifting. You’ll get autocomplete for response fields, fewer duplicate hooks, and a consistent caching strategy across your app.