With Orval
Orval generates typed API clients from OpenAPI specs. By default it uses Axios under the hood, so responses have { status, data } — use the adapter option to normalize them.
import { createExpectStatus, adapters } from "expect-status";
export const expectStatus = createExpectStatus({ adapter: adapters.axios, fallbackMessage: "Request failed.", defaults: { 401: "Please sign in.", "5xx": "Service unavailable.", },});Orval’s generated functions return Axios responses. The adapter maps
res.data→bodyso expect-status can read it.
Basic usage
Section titled “Basic usage”import { expectStatus } from "@/lib/expect-status";import { createPet, getPetById } from "@/api/petstore";
const pet = await expectStatus(200, getPetById(1));// ^? Pet
const created = await expectStatus( 201, createPet({ name: "Buddy", tag: "dog" }),);With flat dispatch
Section titled “With flat dispatch”const pet = await expectStatus(201, createPet(data), { 400: "Invalid pet data.", 409: (body) => redirect(`/pets/${body.id}`), "5xx": "Service unavailable.",});With TanStack Query (Orval’s default)
Section titled “With TanStack Query (Orval’s default)”Orval can generate TanStack Query hooks. Use expect-status inside custom hooks or wrap the generated ones:
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";import { expectStatus } from "@/lib/expect-status";import { getPetById, createPet } from "@/api/petstore";
function usePet(id: number) { return useQuery({ queryKey: ["pet", id], queryFn: () => expectStatus(200, getPetById(id)), });}
function useCreatePet() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (data: CreatePetBody) => expectStatus(201, createPet(data), { 409: "A pet with that name already exists.", }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["pets"] }); }, });}SafeResult
Section titled “SafeResult”const result = await expectStatus(200, getPetById(1), { throws: false });
if (result.ok) { renderPet(result.data);} else { showError(result.error.message);}Orval config reference
Section titled “Orval config reference”Minimal orval.config.ts for a typed Axios client:
import { defineConfig } from "orval";
export default defineConfig({ petstore: { input: "./petstore.yaml", output: { target: "./src/api/petstore.ts", client: "axios", override: { mutator: { path: "./src/api/axios-instance.ts", name: "customInstance", }, }, }, },});import axios from "axios";
export const customInstance = axios.create({ baseURL: "https://api.example.com", validateStatus: () => true, // let expect-status handle errors});
export default customInstance;See also
Section titled “See also”- Orval documentation
- With Axios — Axios adapter details
- With TanStack Query — query and mutation patterns