queryOptions
The queryOptions method allows you to construct type-safe Query Options.
queryOptions can be used together with @tanstack/react-query APIs that take query options, such as useQuery, useQueries, usePrefetchQuery and QueryClient.fetchQuery among many others.
If you would like to use a query API that is not explicitly supported by openapi-typesafe-react-query, this is the way to go.
Examples
useQuery example rewritten using queryOptions.
import { useQuery } from '@tanstack/react-query';
import { $api } from "./api";
export const App = () => {
const { data, error, isLoading } = useQuery(
$api.queryOptions("get", "/users/{user_id}", {
params: {
path: { user_id: 5 },
},
}),
);
if (error) return `An error occurred: ${error.message}`;
if (!data || isLoading) return "Loading...";
return <div>{data.firstname}</div>;
};import createFetchClient from "openapi-typesafe-fetch";
import createClient from "openapi-typesafe-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typesafe
const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
export const $api = createClient(fetchClient);Good to Know
Both useQuery and useSuspenseQuery use queryOptions under the hood.
Usage with useQueries.
import { useQueries } from '@tanstack/react-query';
import { $api } from "./api";
export const useUsersById = (userIds: number[]) => (
useQueries({
queries: userIds.map((userId) => (
$api.queryOptions("get", "/users/{user_id}", {
params: {
path: { user_id: userId },
},
})
))
})
);import createFetchClient from "openapi-typesafe-fetch";
import createClient from "openapi-typesafe-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typesafe
const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
export const $api = createClient(fetchClient);A helper that takes the same arguments
Parameters<typeof $api.queryOptions> takes the arguments of any operation, so a helper can pass them on. TypeScript does not relate the method, the path and the init in it: it checks the path against every path, and the init is required when some operation requires one, so pass {} for a path that needs none (useInvalidateQuery("get", "/items", {})).
import { useQueryClient } from "@tanstack/react-query";
import { $api } from "./api";
export function useInvalidateQuery(...args: Parameters<typeof $api.queryOptions>) {
const queryClient = useQueryClient();
const { queryKey } = $api.queryOptions(...args);
return () => queryClient.invalidateQueries({ queryKey });
}With TypeScript 7 and a schema with hundreds of paths, this Parameters type is over the compiler's limit (TS2859, excessive complexity): it relates every method to every path. List the arguments of the paths the helper takes instead, such as (path: "/users/{user_id}", init: ...).
ReturnType<typeof $api.queryOptions> is still any, as for the hooks: TypeScript does not match these generic signatures against the (...args: any) => infer R pattern of ReturnType, and ReturnType then falls back to any. Take the arguments, as above, or the QueryKey type, instead of the result.
Api
$api.queryOptions(method, path, options, queryOptions);Arguments
method(required)- The HTTP method to use for the request.
- The method is used as key. See Query Keys for more information.
path(required)- The pathname to use for the request.
- Must be an available path for the given method in your schema.
- The pathname is used as key. See Query Keys for more information.
options- The fetch options to use for the request.
- Only required if the OpenApi schema requires parameters.
- The whole options object (
params,headers,bodyand the rest) is part of the key. See Query Keys for more information.
queryOptions- Additional query options to pass through.
Returns
- Query Options
- Fully typed thus
dataanderrorwill be correctly inferred. queryKeyis[method, path, options], or[method, path]without options.optionsis the whole object passed asinit({ params: { path: { id: 1 } } }), not only itsparams.queryFnis set to a fetcher function.
- Fully typed thus