openapi-typescript icon indicating copy to clipboard operation
openapi-typescript copied to clipboard

feat(openapi-react-query): use `queryOptions` helper

Open freshgiammi opened this issue 1 year ago • 8 comments

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.

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

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

freshgiammi avatar Oct 16 '24 19:10 freshgiammi

⚠️ No Changeset found

Latest commit: fb53233e5fc4a71c26574ed3565592f4e08257e8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

changeset-bot[bot] avatar Oct 16 '24 19:10 changeset-bot[bot]

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 https://github.com/openapi-ts/openapi-typescript/pull/1952 superseed this?

freshgiammi avatar Oct 21 '24 13:10 freshgiammi

@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.

freshgiammi avatar Oct 22 '24 09:10 freshgiammi

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>();
+    });
   });

zsugabubus avatar Oct 22 '24 18:10 zsugabubus

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 avatar Oct 28 '24 11:10 kerwanp

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?

drwpow avatar Jan 25 '25 22:01 drwpow

Deploy Preview for openapi-ts ready!

Name Link
Latest commit fb53233e5fc4a71c26574ed3565592f4e08257e8
Latest deploy log https://app.netlify.com/projects/openapi-ts/deploys/6797c394d15dbf00080c8462
Deploy Preview https://deploy-preview-1950--openapi-ts.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Jan 27 '25 17:01 netlify[bot]

@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 👍

freshgiammi avatar Jan 27 '25 17:01 freshgiammi

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

abhiaagarwal avatar May 16 '25 19:05 abhiaagarwal

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

irsooti avatar Oct 14 '25 12:10 irsooti