Skip to content

Comments

feat(openapi-react-query): use DataTag for queryKey in queryOptions#1950

Merged
drwpow merged 1 commit intoopenapi-ts:mainfrom
freshgiammi:freshgiammi/react-query-queryoptions
Feb 12, 2026
Merged

feat(openapi-react-query): use DataTag for queryKey in queryOptions#1950
drwpow merged 1 commit intoopenapi-ts:mainfrom
freshgiammi:freshgiammi/react-query-queryoptions

Conversation

@freshgiammi
Copy link
Contributor

@freshgiammi freshgiammi commented Oct 16, 2024

Changes

The current state of queryOptions doesn't take advantage of the `queryOptions` helper, which has the ability of linking the returned data shape to the queryKey. This is useful when using `queryClient.getQueryData` and especially handy for optimistic updates managed via `queryClient.setQueryData`.

The proposed implementation only consumes the helper to build the queryOptions property, and doesn't touch the way options are passed to useQuery/useSuspenseQuery to avoid narrowing the allowed options to the ones provided by the helper.

Currently, return data/error types for queries are not mapped to their queryKey when this is retrieved from queryOptions.

Since using the queryOptions helper itself is rather complex due to the function overloads, manually tag the queryKey with the correct Response["data"] and Response["error"] types.

This fixes data being unknown when accessed via queryClient.setQueryData(queryKey).

How to Review

When consuming queryClient.getQueryData by providing a queryKey coming from a queryOptions object, see that the returned type isn't unknown anymore, but Response['data'] | undefined.

Checklist

  • Unit tests updated
  • docs/ updated (if necessary)
  • pnpm run update:examples run (only applicable for openapi-typescript)

@freshgiammi freshgiammi requested a review from a team as a code owner October 16, 2024 19:04
@changeset-bot
Copy link

changeset-bot bot commented Oct 16, 2024

🦋 Changeset detected

Latest commit: 4b98a33

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openapi-react-query Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

@zsugabubus zsugabubus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about simply changing return type of QueryOptionsFunction to be queryKey: DataTag<...>, just like what queryOptions does internally? I think it would cause less complications than this overloaded stuff.

@freshgiammi
Copy link
Contributor Author

Probably a better idea, seeing that complexity is growing with SkipToken (even though I'm not too sure of the implications).
You want to take care of this your PR and have #1952 superseed this?

@freshgiammi
Copy link
Contributor Author

@zsugabubus welp it looks like we're out of luck. Either we ask for the symbol to be exported, or we have to rely on the overloads... unless you have a better idea, I'm not sure of alternatives here.

@zsugabubus
Copy link
Contributor

The below code works fine for me. I guess we don't need to actually assign anything, dataTagSymbol is used by the type system only and no code will ever read this variable. I could be more precise with the typing instead of an as any but I think that would too verbose with little added value.

diff against my PR
 packages/openapi-react-query/src/index.ts        |  6 ++++--
 packages/openapi-react-query/test/index.test.tsx | 11 +++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/packages/openapi-react-query/src/index.ts b/packages/openapi-react-query/src/index.ts
index 97d83a6..01f848b 100644
--- a/packages/openapi-react-query/src/index.ts
+++ b/packages/openapi-react-query/src/index.ts
@@ -10,2 +10,3 @@ import {
   type SkipToken,
+  type DataTag,
   useMutation,
@@ -43,3 +44,3 @@ export type QueryOptionsFunction<Paths extends Record<string, Record<HttpMethod,
     UseQueryOptions<Response["data"], Response["error"], Response["data"], QueryKey<Paths, Method, Path>>,
-    "queryFn"
+    "queryFn" | "queryKey"
   > & {
@@ -49,2 +50,3 @@ export type QueryOptionsFunction<Paths extends Record<string, Record<HttpMethod,
     >;
+    queryKey: DataTag<QueryKey<Paths, Method, Path>, Response["data"]>;
   }
@@ -124,3 +126,3 @@ export default function createClient<Paths extends {}, Media extends MediaType =
   const queryOptions: QueryOptionsFunction<Paths, Media> = (method, path, ...[init, options]) => ({
-    queryKey: [method, path, init as InitWithUnknowns<typeof init>] as const,
+    queryKey: [method, path, init as InitWithUnknowns<typeof init>] as const as any,
     queryFn,
diff --git a/packages/openapi-react-query/test/index.test.tsx b/packages/openapi-react-query/test/index.test.tsx
index 97550d4..06ebfa7 100644
--- a/packages/openapi-react-query/test/index.test.tsx
+++ b/packages/openapi-react-query/test/index.test.tsx
@@ -233,2 +233,13 @@ describe("client", () => {
     });
+
+    it("returns queryKey that allows data to be inferred", async () => {
+      const fetchClient = createFetchClient<paths>();
+      const client = createClient(fetchClient);
+
+      const { queryKey } = client.queryOptions("get", "/string-array");
+
+      const data = queryClient.getQueryData(queryKey);
+
+      expectTypeOf(data).toEqualTypeOf<string[] | undefined>();
+    });
   });

@drwpow drwpow added the openapi-react-query Relevant to openapi-react-query label Oct 25, 2024
@kerwanp
Copy link
Contributor

kerwanp commented Oct 28, 2024

I think it is a good idea to rely on tanstack-query helper types as much as possible. When I originally wrote this library I went straight to the point but now when using more complex features the types are not correct (queryOptions, callbacks, etc).

@kerwanp kerwanp added stale and removed stale labels Dec 19, 2024
@drwpow
Copy link
Contributor

drwpow commented Jan 25, 2025

Sorry for the delay on this. We’ve merged some other PRs that have caused this PR to fall out of line with main.

Would love if you could rebase. It seems like this PR could still be useful?

@freshgiammi freshgiammi force-pushed the freshgiammi/react-query-queryoptions branch from 3e149be to db243c6 Compare January 27, 2025 17:30
@netlify
Copy link

netlify bot commented Jan 27, 2025

👷 Deploy request for openapi-ts pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 4b98a33

@freshgiammi
Copy link
Contributor Author

@drwpow no problem, I've had a couple of busy months as well and couldn't keep this updated. Just rebased, let me know if there's anything else I can do 👍

@abhiaagarwal
Copy link

Status on this? I use optimistic updates a lot, this would be a wonderful QOL improvement :)

@irsooti
Copy link

irsooti commented Oct 14, 2025

What's missing here? It's a huge ergonomic feature to have

@freshgiammi
Copy link
Contributor Author

freshgiammi commented Feb 9, 2026

Hello, I've rebased the PR and changed the approach used here, considering the challenge of using the queryOptions helper due to function overloads. I've updated the PR description accordingly, but tldr; we're manually tagging the queryKey (which is what the helper does as well) to make sure the data/error types for the query are attached to the queryKey.

This PR has been open for quite a while, can we get this reviewed?

cc @drwpow @kerwanp

@drwpow
Copy link
Contributor

drwpow commented Feb 11, 2026

Thanks for your patience, we’re getting caught up on reviews. Could you add a patch changeset (see comment) and we can get it released? We’re using patch on 0.x to signal any sort of backwards-compatible change and this seems like it is. With a changeset, happy to approve & release.

Also, in case you missed it, we will be stopping development on this package and returning to just working on openapi-typescript to make better use of our limited resources. So we‘re going to release in-flight PRs like this one, but just know after maybe a few more releases (~3 months or so) this package will be frozen.

@freshgiammi freshgiammi force-pushed the freshgiammi/react-query-queryoptions branch from c2562a4 to 4b98a33 Compare February 12, 2026 14:20
@freshgiammi
Copy link
Contributor Author

Changeset added!


No worries! I didn't see the discussion, and I'm sad that fetch and react-query packages are being deprecated.
I definitely fall into the category of trivial users (tanstack-router with multiple non-ts api services), but I completely understand and agree with the points you raised.

Given that both libraries are relatively small, we should be able to re-implement them should the need arise. I'm looking forward to the guide and to openapi-typescript v8 (and especially validation, hopefully with something that supports standard-schema)!

Still, thank you for these libraries: they've been such a breeze to work with compared to other solutions we've tried.

@freshgiammi freshgiammi changed the title feat(openapi-react-query): use queryOptions helper feat(openapi-react-query): use DataTag for queryKey in queryOptions Feb 12, 2026
@drwpow drwpow merged commit ac9d082 into openapi-ts:main Feb 12, 2026
7 checks passed
@openapi-ts-bot openapi-ts-bot mentioned this pull request Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

openapi-react-query Relevant to openapi-react-query

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants