diff --git a/packages/clients/tanstack-query/src/react.ts b/packages/clients/tanstack-query/src/react.ts index 15bfbb51..a8f55b9c 100644 --- a/packages/clients/tanstack-query/src/react.ts +++ b/packages/clients/tanstack-query/src/react.ts @@ -57,7 +57,7 @@ import { type ExtraMutationOptions, type ExtraQueryOptions, } from './utils/common'; -import type { TrimDelegateModelOperations } from './utils/types'; +import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types'; export type { FetchFn } from './utils/common'; @@ -93,12 +93,14 @@ function useHooksContext() { export type ModelQueryOptions = Omit, 'queryKey'> & ExtraQueryOptions; -export type ModelQueryResult = UseQueryResult & { queryKey: QueryKey }; +export type ModelQueryResult = UseQueryResult, DefaultError> & { queryKey: QueryKey }; export type ModelSuspenseQueryOptions = Omit, 'queryKey'> & ExtraQueryOptions; -export type ModelSuspenseQueryResult = UseSuspenseQueryResult & { queryKey: QueryKey }; +export type ModelSuspenseQueryResult = UseSuspenseQueryResult, DefaultError> & { + queryKey: QueryKey; +}; export type ModelInfiniteQueryOptions = Omit< UseInfiniteQueryOptions>, diff --git a/packages/clients/tanstack-query/src/svelte.ts b/packages/clients/tanstack-query/src/svelte.ts index 33cf86bd..3cd81476 100644 --- a/packages/clients/tanstack-query/src/svelte.ts +++ b/packages/clients/tanstack-query/src/svelte.ts @@ -54,7 +54,7 @@ import { type ExtraMutationOptions, type ExtraQueryOptions, } from './utils/common'; -import type { TrimDelegateModelOperations } from './utils/types'; +import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types'; export type { FetchFn } from './utils/common'; @@ -91,7 +91,9 @@ function getQuerySettings() { export type ModelQueryOptions = Omit, 'queryKey'> & ExtraQueryOptions; -export type ModelQueryResult = Readable> & { queryKey: QueryKey }>; +export type ModelQueryResult = Readable< + UnwrapStore, DefaultError>> & { queryKey: QueryKey } +>; export type ModelInfiniteQueryOptions = Omit< CreateInfiniteQueryOptions>, diff --git a/packages/clients/tanstack-query/src/utils/types.ts b/packages/clients/tanstack-query/src/utils/types.ts index ac7829e9..7a5f32ef 100644 --- a/packages/clients/tanstack-query/src/utils/types.ts +++ b/packages/clients/tanstack-query/src/utils/types.ts @@ -30,3 +30,20 @@ export type TrimDelegateModelOperations< Model extends GetModels, T extends Record, > = IsDelegateModel extends true ? Omit : T; + +export type WithOptimistic = + T extends Array + ? Array< + U & { + /** + * Indicates if the item is in an optimistic update state + */ + $optimistic?: boolean; + } + > + : T & { + /** + * Indicates if the item is in an optimistic update state + */ + $optimistic?: boolean; + }; diff --git a/packages/clients/tanstack-query/src/vue.ts b/packages/clients/tanstack-query/src/vue.ts index 8239ce97..2623f014 100644 --- a/packages/clients/tanstack-query/src/vue.ts +++ b/packages/clients/tanstack-query/src/vue.ts @@ -52,7 +52,7 @@ import { type ExtraMutationOptions, type ExtraQueryOptions, } from './utils/common'; -import type { TrimDelegateModelOperations } from './utils/types'; +import type { TrimDelegateModelOperations, WithOptimistic } from './utils/types'; export type { FetchFn } from './utils/common'; export const VueQueryContextKey = 'zenstack-vue-query-context'; @@ -86,7 +86,7 @@ export type ModelQueryOptions = MaybeRefOrGetter< Omit>, 'queryKey'> & ExtraQueryOptions >; -export type ModelQueryResult = UseQueryReturnType & { queryKey: QueryKey }; +export type ModelQueryResult = UseQueryReturnType, DefaultError> & { queryKey: QueryKey }; export type ModelInfiniteQueryOptions = MaybeRefOrGetter< Omit>>, 'queryKey' | 'initialPageParam'> diff --git a/packages/clients/tanstack-query/test/react-typing-test.ts b/packages/clients/tanstack-query/test/react-typing-test.ts index 02d7a2e3..8f57ec67 100644 --- a/packages/clients/tanstack-query/test/react-typing-test.ts +++ b/packages/clients/tanstack-query/test/react-typing-test.ts @@ -16,8 +16,10 @@ check(client.user.useFindUnique({ select: { email: true } }).data.name); check(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } }).data?.posts[0]?.title); check(client.user.useFindFirst().data?.email); +check(client.user.useFindFirst().data?.$optimistic); check(client.user.useFindMany().data?.[0]?.email); +check(client.user.useFindMany().data?.[0]?.$optimistic); check(client.user.useInfiniteFindMany().data?.pages[0]?.[0]?.email); check( @@ -28,6 +30,8 @@ check( }, ).data?.pages[1]?.[0]?.email, ); +// @ts-expect-error +check(client.user.useInfiniteFindMany().data?.pages[0]?.[0]?.$optimistic); check(client.user.useSuspenseFindMany().data[0]?.email); check(client.user.useSuspenseInfiniteFindMany().data.pages[0]?.[0]?.email); diff --git a/packages/clients/tanstack-query/test/svelte-typing-test.ts b/packages/clients/tanstack-query/test/svelte-typing-test.ts index 62735112..dff02583 100644 --- a/packages/clients/tanstack-query/test/svelte-typing-test.ts +++ b/packages/clients/tanstack-query/test/svelte-typing-test.ts @@ -17,8 +17,11 @@ check(get(client.user.useFindUnique({ select: { email: true } })).data.name); check(get(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } })).data?.posts[0]?.title); check(get(client.user.useFindFirst()).data?.email); +check(get(client.user.useFindFirst()).data?.$optimistic); check(get(client.user.useFindMany()).data?.[0]?.email); +check(get(client.user.useFindMany()).data?.[0]?.$optimistic); + check(get(client.user.useInfiniteFindMany()).data?.pages[0]?.[0]?.email); check( get( @@ -30,6 +33,8 @@ check( ), ).data?.pages[1]?.[0]?.email, ); +// @ts-expect-error +check(get(client.user.useInfiniteFindMany()).data?.pages[0]?.[0]?.$optimistic); check(get(client.user.useCount()).data?.toFixed(2)); check(get(client.user.useCount({ select: { email: true } })).data?.email.toFixed(2)); diff --git a/packages/clients/tanstack-query/test/vue-typing-test.ts b/packages/clients/tanstack-query/test/vue-typing-test.ts index 07b980c5..f134378c 100644 --- a/packages/clients/tanstack-query/test/vue-typing-test.ts +++ b/packages/clients/tanstack-query/test/vue-typing-test.ts @@ -16,8 +16,10 @@ check(client.user.useFindUnique({ select: { email: true } }).data.name); check(client.user.useFindUnique({ where: { id: '1' }, include: { posts: true } }).data.value?.posts[0]?.title); check(client.user.useFindFirst().data.value?.email); +check(client.user.useFindFirst().data.value?.$optimistic); check(client.user.useFindMany().data.value?.[0]?.email); +check(client.user.useFindMany().data.value?.[0]?.$optimistic); check(client.user.useInfiniteFindMany().data.value?.pages[0]?.[0]?.email); check( @@ -28,6 +30,8 @@ check( }, ).data.value?.pages[1]?.[0]?.email, ); +// @ts-expect-error +check(client.user.useInfiniteFindMany().data.value?.pages[0]?.[0]?.$optimistic); check(client.user.useCount().data.value?.toFixed(2)); check(client.user.useCount({ select: { email: true } }).data.value?.email.toFixed(2));