Skip to content

Commit 51015d4

Browse files
thomasballingerConvex, Inc.
authored and
Convex, Inc.
committed
Fix React Query types (#31002)
New React Query types don't allow skipToken for useSuspenseQuery. Fix @convex-dev/react-query types to match this. GitOrigin-RevId: e59e9308573ebdfc2e4d5556baa9dba2aaef8eca
1 parent 76b6693 commit 51015d4

File tree

5 files changed

+119
-24
lines changed

5 files changed

+119
-24
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@convex-dev/react-query",
3-
"version": "0.0.0-alpha.6",
3+
"version": "0.0.0-alpha.7",
44
"license": "Apache-2.0",
55
"type": "module",
66
"scripts": {
@@ -53,7 +53,8 @@
5353
"react-dom": "^18.0.0",
5454
"tshy": "^2.0.0",
5555
"typescript": "~5.0.3",
56-
"vite": "5.2.14"
56+
"vite": "5.2.14",
57+
"vitest": "~1.6.0"
5758
},
5859
"exports": {
5960
".": {

src/example.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
QueryClientProvider,
55
useMutation,
66
useQuery,
7+
useSuspenseQuery,
78
} from "@tanstack/react-query";
89
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
910
import { ConvexProvider, ConvexReactClient } from "convex/react";
@@ -51,7 +52,7 @@ function Weather() {
5152
// This query doesn't update reactively, it refetches like a normal queryFn.
5253
convexAction(api.weather.getSFWeather, {}),
5354
);
54-
if (isPending || error) return "?";
55+
if (isPending || error) return <span>?</span>;
5556
const fetchedAt = new Date(data.fetchedAt);
5657
return (
5758
<div className="weather">

src/index.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
2+
import { test, describe } from "vitest";
3+
import { convexAction, convexQuery } from "./index.js";
4+
import { api } from "../convex/_generated/api.js";
5+
6+
describe("query options factory types", () => {
7+
test("with useQuery", () => {
8+
if (1 + 2 === 3) return; // test types only
9+
10+
type ActionFunc = typeof api.weather.getSFWeather;
11+
{
12+
const action = convexAction(api.weather.getSFWeather, {});
13+
const result = useQuery(action);
14+
const data: ActionFunc["_returnType"] | undefined = result.data;
15+
console.log(data);
16+
}
17+
18+
{
19+
const action = convexAction(api.weather.getSFWeather, "skip");
20+
const result = useQuery(action);
21+
// Skip doesn't need to cause data in types since there's no point
22+
// to always passing "skip".
23+
const data: ActionFunc["_returnType"] | undefined = result.data;
24+
console.log(data);
25+
26+
// @ts-expect-error Actions with "skip" can't be used with useSuspenseQuery
27+
useSuspenseQuery(action);
28+
}
29+
30+
type QueryFunc = typeof api.messages.list;
31+
{
32+
const query = convexQuery(api.messages.list, {});
33+
const result = useQuery(query);
34+
const data: QueryFunc["_returnType"] | undefined = result.data;
35+
console.log(data);
36+
}
37+
38+
{
39+
const query = convexQuery(api.messages.list, "skip");
40+
const result = useQuery(query);
41+
// Skip doesn't need to cause data in types since there's no point
42+
// to always passing "skip".
43+
const data: QueryFunc["_returnType"] | undefined = result.data;
44+
console.log(data);
45+
46+
// @ts-expect-error Queries with "skip" can't be used with useSuspenseQuery
47+
useSuspenseQuery(query);
48+
}
49+
});
50+
});

src/index.ts

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
QueryFunctionContext,
66
QueryKey,
77
UseQueryOptions,
8+
UseSuspenseQueryOptions,
89
hashKey,
910
notifyManager,
1011
} from "@tanstack/react-query";
@@ -415,18 +416,37 @@ export class ConvexQueryClient {
415416
*/
416417
export const convexQuery = <
417418
ConvexQueryReference extends FunctionReference<"query">,
419+
Args extends FunctionArgs<ConvexQueryReference> | "skip",
418420
>(
419421
funcRef: ConvexQueryReference,
420-
queryArgs: FunctionArgs<ConvexQueryReference>,
421-
): Pick<
422-
UseQueryOptions<
423-
FunctionReturnType<ConvexQueryReference>,
424-
Error,
425-
FunctionReturnType<ConvexQueryReference>,
426-
["convexQuery", ConvexQueryReference, FunctionArgs<ConvexQueryReference>]
427-
>,
428-
"queryKey" | "queryFn" | "staleTime"
429-
> => {
422+
queryArgs: Args,
423+
): Args extends "skip"
424+
? Pick<
425+
UseQueryOptions<
426+
FunctionReturnType<ConvexQueryReference>,
427+
Error,
428+
FunctionReturnType<ConvexQueryReference>,
429+
[
430+
"convexQuery",
431+
ConvexQueryReference,
432+
FunctionArgs<ConvexQueryReference>,
433+
]
434+
>,
435+
"queryKey" | "queryFn" | "staleTime" | "enabled"
436+
>
437+
: Pick<
438+
UseSuspenseQueryOptions<
439+
FunctionReturnType<ConvexQueryReference>,
440+
Error,
441+
FunctionReturnType<ConvexQueryReference>,
442+
[
443+
"convexQuery",
444+
ConvexQueryReference,
445+
FunctionArgs<ConvexQueryReference>,
446+
]
447+
>,
448+
"queryKey" | "queryFn" | "staleTime"
449+
> => {
430450
return {
431451
queryKey: [
432452
"convexQuery",
@@ -436,6 +456,7 @@ export const convexQuery = <
436456
queryArgs,
437457
],
438458
staleTime: Infinity,
459+
...(queryArgs === "skip" ? { enabled: false } : {}),
439460
};
440461
};
441462

@@ -458,18 +479,37 @@ export const convexQuery = <
458479
*/
459480
export const convexAction = <
460481
ConvexActionReference extends FunctionReference<"action">,
482+
Args extends FunctionArgs<ConvexActionReference> | "skip",
461483
>(
462484
funcRef: ConvexActionReference,
463-
args: FunctionArgs<ConvexActionReference>,
464-
): Pick<
465-
UseQueryOptions<
466-
FunctionReturnType<ConvexActionReference>,
467-
Error,
468-
FunctionReturnType<ConvexActionReference>,
469-
["convexAction", ConvexActionReference, FunctionArgs<ConvexActionReference>]
470-
>,
471-
"queryKey" | "queryFn" | "staleTime"
472-
> => {
485+
args: Args,
486+
): Args extends "skip"
487+
? Pick<
488+
UseQueryOptions<
489+
FunctionReturnType<ConvexActionReference>,
490+
Error,
491+
FunctionReturnType<ConvexActionReference>,
492+
[
493+
"convexAction",
494+
ConvexActionReference,
495+
FunctionArgs<ConvexActionReference>,
496+
]
497+
>,
498+
"queryKey" | "queryFn" | "staleTime" | "enabled"
499+
>
500+
: Pick<
501+
UseSuspenseQueryOptions<
502+
FunctionReturnType<ConvexActionReference>,
503+
Error,
504+
FunctionReturnType<ConvexActionReference>,
505+
[
506+
"convexAction",
507+
ConvexActionReference,
508+
FunctionArgs<ConvexActionReference>,
509+
]
510+
>,
511+
"queryKey" | "queryFn" | "staleTime"
512+
> => {
473513
return {
474514
queryKey: [
475515
"convexAction",
@@ -478,6 +518,7 @@ export const convexAction = <
478518
// TODO bigints are not serializable
479519
args,
480520
],
521+
...(args === "skip" ? { enabled: false } : {}),
481522
};
482523
};
483524

tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"target": "ES2020",
3+
"target": "ES2022",
44
"useDefineForClassFields": true,
55
"lib": ["ES2020", "DOM", "DOM.Iterable"],
66
"module": "NodeNext",
@@ -15,6 +15,8 @@
1515
"declaration": true,
1616
"declarationMap": true,
1717
"sourceMap": true,
18+
/* for vitest :/ */
19+
"skipLibCheck": true,
1820

1921
"strict": true,
2022

0 commit comments

Comments
 (0)