Skip to content

Commit c2562a4

Browse files
committed
feat(openapi-react-query): use DataTag for queryKey in queryOptions
1 parent 79a443b commit c2562a4

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

packages/openapi-react-query/src/index.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
type DataTag,
23
type InfiniteData,
34
type QueryClient,
45
type QueryFunctionContext,
@@ -65,8 +66,9 @@ export type QueryOptionsFunction<Paths extends Record<string, Record<HttpMethod,
6566
InferSelectReturnType<Response["data"], Options["select"]>,
6667
QueryKey<Paths, Method, Path>
6768
>,
68-
"queryFn"
69+
"queryFn" | "queryKey"
6970
> & {
71+
queryKey: DataTag<QueryKey<Paths, Method, Path>, Response["data"], Response["error"]>;
7072
queryFn: Exclude<
7173
UseQueryOptions<
7274
Response["data"],
@@ -209,10 +211,10 @@ export default function createClient<Paths extends {}, Media extends MediaType =
209211
};
210212

211213
const queryOptions: QueryOptionsFunction<Paths, Media> = (method, path, ...[init, options]) => ({
212-
queryKey: (init === undefined ? ([method, path] as const) : ([method, path, init] as const)) as QueryKey<
213-
Paths,
214-
typeof method,
215-
typeof path
214+
queryKey: (init === undefined ? ([method, path] as const) : ([method, path, init] as const)) as DataTag<
215+
QueryKey<Paths, typeof method, typeof path>,
216+
any,
217+
any
216218
>,
217219
queryFn,
218220
...options,

packages/openapi-react-query/test/index.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,49 @@ describe("client", () => {
9191
client.queryOptions("get", "/blogposts/{post_id}", {});
9292
});
9393

94+
it("correctly infers return type from query key", async () => {
95+
const fetchClient = createFetchClient<paths>({ baseUrl });
96+
const client = createClient(fetchClient);
97+
98+
const initialData = { title: "Initial data", body: "Initial data" };
99+
100+
const options = client.queryOptions(
101+
"get",
102+
"/blogposts/{post_id}",
103+
{
104+
params: {
105+
path: {
106+
post_id: "1",
107+
},
108+
},
109+
},
110+
{
111+
initialData: () => initialData,
112+
},
113+
);
114+
115+
const data = queryClient.getQueryData(options.queryKey);
116+
117+
expectTypeOf(data).toEqualTypeOf<
118+
| {
119+
title: string;
120+
body: string;
121+
publish_date?: number;
122+
}
123+
| undefined
124+
>();
125+
expect(data).toEqual(undefined);
126+
127+
const { result } = renderHook(() => useQuery({ ...options, enabled: false, select: (data) => data }), {
128+
wrapper,
129+
});
130+
131+
await waitFor(() => expect(result.current.isFetching).toBe(false));
132+
133+
expect(result.current.data).toEqual(initialData);
134+
expect(result.current.error).toBeNull();
135+
});
136+
94137
it("returns query options that can resolve data correctly with fetchQuery", async () => {
95138
const response = { title: "title", body: "body" };
96139
const fetchClient = createFetchClient<paths>({ baseUrl });

0 commit comments

Comments
 (0)