Skip to content

Commit 81924d9

Browse files
authored
fix(tanstack): query result $optimistic typing (#372)
* fix(tanstack): query result $optimistic typing * update
1 parent 5355474 commit 81924d9

File tree

7 files changed

+41
-7
lines changed

7 files changed

+41
-7
lines changed

packages/clients/tanstack-query/src/react.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import {
5757
type ExtraMutationOptions,
5858
type ExtraQueryOptions,
5959
} from './utils/common';
60-
import type { TrimDelegateModelOperations } from './utils/types';
60+
import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types';
6161

6262
export type { FetchFn } from './utils/common';
6363

@@ -93,12 +93,14 @@ function useHooksContext() {
9393

9494
export type ModelQueryOptions<T> = Omit<UseQueryOptions<T, DefaultError>, 'queryKey'> & ExtraQueryOptions;
9595

96-
export type ModelQueryResult<T> = UseQueryResult<T, DefaultError> & { queryKey: QueryKey };
96+
export type ModelQueryResult<T> = UseQueryResult<WithOptimistic<T>, DefaultError> & { queryKey: QueryKey };
9797

9898
export type ModelSuspenseQueryOptions<T> = Omit<UseSuspenseQueryOptions<T, DefaultError>, 'queryKey'> &
9999
ExtraQueryOptions;
100100

101-
export type ModelSuspenseQueryResult<T> = UseSuspenseQueryResult<T, DefaultError> & { queryKey: QueryKey };
101+
export type ModelSuspenseQueryResult<T> = UseSuspenseQueryResult<WithOptimistic<T>, DefaultError> & {
102+
queryKey: QueryKey;
103+
};
102104

103105
export type ModelInfiniteQueryOptions<T> = Omit<
104106
UseInfiniteQueryOptions<T, DefaultError, InfiniteData<T>>,

packages/clients/tanstack-query/src/svelte.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import {
5454
type ExtraMutationOptions,
5555
type ExtraQueryOptions,
5656
} from './utils/common';
57-
import type { TrimDelegateModelOperations } from './utils/types';
57+
import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types';
5858

5959
export type { FetchFn } from './utils/common';
6060

@@ -91,7 +91,9 @@ function getQuerySettings() {
9191

9292
export type ModelQueryOptions<T> = Omit<CreateQueryOptions<T, DefaultError>, 'queryKey'> & ExtraQueryOptions;
9393

94-
export type ModelQueryResult<T> = Readable<UnwrapStore<CreateQueryResult<T, DefaultError>> & { queryKey: QueryKey }>;
94+
export type ModelQueryResult<T> = Readable<
95+
UnwrapStore<CreateQueryResult<WithOptimistic<T>, DefaultError>> & { queryKey: QueryKey }
96+
>;
9597

9698
export type ModelInfiniteQueryOptions<T> = Omit<
9799
CreateInfiniteQueryOptions<T, DefaultError, InfiniteData<T>>,

packages/clients/tanstack-query/src/utils/types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,20 @@ export type TrimDelegateModelOperations<
3030
Model extends GetModels<Schema>,
3131
T extends Record<string, unknown>,
3232
> = IsDelegateModel<Schema, Model> extends true ? Omit<T, HooksOperationsIneligibleForDelegateModels> : T;
33+
34+
export type WithOptimistic<T> =
35+
T extends Array<infer U>
36+
? Array<
37+
U & {
38+
/**
39+
* Indicates if the item is in an optimistic update state
40+
*/
41+
$optimistic?: boolean;
42+
}
43+
>
44+
: T & {
45+
/**
46+
* Indicates if the item is in an optimistic update state
47+
*/
48+
$optimistic?: boolean;
49+
};

packages/clients/tanstack-query/src/vue.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {
5252
type ExtraMutationOptions,
5353
type ExtraQueryOptions,
5454
} from './utils/common';
55-
import type { TrimDelegateModelOperations } from './utils/types';
55+
import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types';
5656

5757
export type { FetchFn } from './utils/common';
5858
export const VueQueryContextKey = 'zenstack-vue-query-context';
@@ -86,7 +86,7 @@ export type ModelQueryOptions<T> = MaybeRefOrGetter<
8686
Omit<UnwrapRef<UseQueryOptions<T, DefaultError>>, 'queryKey'> & ExtraQueryOptions
8787
>;
8888

89-
export type ModelQueryResult<T> = UseQueryReturnType<T, DefaultError> & { queryKey: QueryKey };
89+
export type ModelQueryResult<T> = UseQueryReturnType<WithOptimistic<T>, DefaultError> & { queryKey: QueryKey };
9090

9191
export type ModelInfiniteQueryOptions<T> = MaybeRefOrGetter<
9292
Omit<UnwrapRef<UseInfiniteQueryOptions<T, DefaultError, InfiniteData<T>>>, 'queryKey' | 'initialPageParam'>

packages/clients/tanstack-query/test/react-typing-test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ check(client.user.useFindUnique({ select: { email: true } }).data.name);
1616
check(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } }).data?.posts[0]?.title);
1717

1818
check(client.user.useFindFirst().data?.email);
19+
check(client.user.useFindFirst().data?.$optimistic);
1920

2021
check(client.user.useFindMany().data?.[0]?.email);
22+
check(client.user.useFindMany().data?.[0]?.$optimistic);
2123

2224
check(client.user.useInfiniteFindMany().data?.pages[0]?.[0]?.email);
2325
check(
@@ -28,6 +30,8 @@ check(
2830
},
2931
).data?.pages[1]?.[0]?.email,
3032
);
33+
// @ts-expect-error
34+
check(client.user.useInfiniteFindMany().data?.pages[0]?.[0]?.$optimistic);
3135

3236
check(client.user.useSuspenseFindMany().data[0]?.email);
3337
check(client.user.useSuspenseInfiniteFindMany().data.pages[0]?.[0]?.email);

packages/clients/tanstack-query/test/svelte-typing-test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ check(get(client.user.useFindUnique({ select: { email: true } })).data.name);
1717
check(get(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } })).data?.posts[0]?.title);
1818

1919
check(get(client.user.useFindFirst()).data?.email);
20+
check(get(client.user.useFindFirst()).data?.$optimistic);
2021

2122
check(get(client.user.useFindMany()).data?.[0]?.email);
23+
check(get(client.user.useFindMany()).data?.[0]?.$optimistic);
24+
2225
check(get(client.user.useInfiniteFindMany()).data?.pages[0]?.[0]?.email);
2326
check(
2427
get(
@@ -30,6 +33,8 @@ check(
3033
),
3134
).data?.pages[1]?.[0]?.email,
3235
);
36+
// @ts-expect-error
37+
check(get(client.user.useInfiniteFindMany()).data?.pages[0]?.[0]?.$optimistic);
3338

3439
check(get(client.user.useCount()).data?.toFixed(2));
3540
check(get(client.user.useCount({ select: { email: true } })).data?.email.toFixed(2));

packages/clients/tanstack-query/test/vue-typing-test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ check(client.user.useFindUnique({ select: { email: true } }).data.name);
1616
check(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } }).data.value?.posts[0]?.title);
1717

1818
check(client.user.useFindFirst().data.value?.email);
19+
check(client.user.useFindFirst().data.value?.$optimistic);
1920

2021
check(client.user.useFindMany().data.value?.[0]?.email);
22+
check(client.user.useFindMany().data.value?.[0]?.$optimistic);
2123

2224
check(client.user.useInfiniteFindMany().data.value?.pages[0]?.[0]?.email);
2325
check(
@@ -28,6 +30,8 @@ check(
2830
},
2931
).data.value?.pages[1]?.[0]?.email,
3032
);
33+
// @ts-expect-error
34+
check(client.user.useInfiniteFindMany().data.value?.pages[0]?.[0]?.$optimistic);
3135

3236
check(client.user.useCount().data.value?.toFixed(2));
3337
check(client.user.useCount({ select: { email: true } }).data.value?.email.toFixed(2));

0 commit comments

Comments
 (0)