diff --git a/packages/react-query/src/__tests__/useQueries.test-d.tsx b/packages/react-query/src/__tests__/useQueries.test-d.tsx index 9aaeb45dc2..17bccea688 100644 --- a/packages/react-query/src/__tests__/useQueries.test-d.tsx +++ b/packages/react-query/src/__tests__/useQueries.test-d.tsx @@ -61,19 +61,29 @@ describe('UseQueries config object overload', () => { }) it('should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => { + const queryKey = ['key'] as const + const queryFn = () => Promise.resolve(1) + type TQueryFnData = Awaited> + const query1 = queryOptions({ - queryKey: ['key'], - queryFn: () => Promise.resolve(1), + queryKey, + queryFn, select: (data) => data > 1, }) - const query2 = { - queryKey: ['key'], - queryFn: () => Promise.resolve(1), - select: (data: number) => data > 1, - } - - const queryResults = useQueries({ queries: [query1, query2] }) + const queryResults = useQueries({ + queries: [ + query1, + { + queryKey, + queryFn, + select: (data) => { + expectTypeOf(data).toEqualTypeOf() + return data > 1 + }, + } satisfies UseQueryOptions, + ] as const, + }) const query1Data = queryResults[0].data const query2Data = queryResults[1].data diff --git a/packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx b/packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx index 76fb13a9f5..298f55dafc 100644 --- a/packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx +++ b/packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx @@ -49,19 +49,29 @@ describe('UseSuspenseQueries config object overload', () => { }) it('should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => { + const queryKey = ['key'] as const + const queryFn = () => Promise.resolve(1) + type TQueryFnData = Awaited> + const query1 = queryOptions({ - queryKey: ['key'], - queryFn: () => Promise.resolve(1), + queryKey, + queryFn, select: (data) => data > 1, }) - const query2 = { - queryKey: ['key'], - queryFn: () => Promise.resolve(1), - select: (data: number) => data > 1, - } - - const queryResults = useSuspenseQueries({ queries: [query1, query2] }) + const queryResults = useSuspenseQueries({ + queries: [ + query1, + { + queryKey, + queryFn, + select: (data) => { + expectTypeOf(data).toEqualTypeOf() + return data > 1 + }, + } satisfies UseQueryOptions, + ] as const, + }) const query1Data = queryResults[0].data const query2Data = queryResults[1].data diff --git a/packages/react-query/src/index.ts b/packages/react-query/src/index.ts index 36ea8da7af..863f9842f8 100644 --- a/packages/react-query/src/index.ts +++ b/packages/react-query/src/index.ts @@ -20,14 +20,20 @@ export { usePrefetchInfiniteQuery } from './usePrefetchInfiniteQuery' export { queryOptions } from './queryOptions' export type { DefinedInitialDataOptions, + DefinedInitialDataOptionsResult, UndefinedInitialDataOptions, + UndefinedInitialDataOptionsResult, UnusedSkipTokenOptions, + UnusedSkipTokenOptionsResult, } from './queryOptions' export { infiniteQueryOptions } from './infiniteQueryOptions' export type { DefinedInitialDataInfiniteOptions, + DefinedInitialDataInfiniteOptionsResult, UndefinedInitialDataInfiniteOptions, + UndefinedInitialDataInfiniteOptionsResult, UnusedSkipTokenInfiniteOptions, + UnusedSkipTokenInfiniteOptionsResult, } from './infiniteQueryOptions' export { QueryClientContext, diff --git a/packages/react-query/src/infiniteQueryOptions.ts b/packages/react-query/src/infiniteQueryOptions.ts index 5e8c371a59..ff4f1af99b 100644 --- a/packages/react-query/src/infiniteQueryOptions.ts +++ b/packages/react-query/src/infiniteQueryOptions.ts @@ -31,6 +31,25 @@ export type UndefinedInitialDataInfiniteOptions< > } +export type UndefinedInitialDataInfiniteOptionsResult< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> = Omit< + UndefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + 'queryKey' +> & { + queryKey: DataTag, TError> +} + export type UnusedSkipTokenInfiniteOptions< TQueryFnData, TError = DefaultError, @@ -53,6 +72,25 @@ export type UnusedSkipTokenInfiniteOptions< > } +export type UnusedSkipTokenInfiniteOptionsResult< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> = Omit< + UnusedSkipTokenInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + 'queryKey' +> & { + queryKey: DataTag, TError> +} + export type DefinedInitialDataInfiniteOptions< TQueryFnData, TError = DefaultError, @@ -72,6 +110,25 @@ export type DefinedInitialDataInfiniteOptions< | undefined } +export type DefinedInitialDataInfiniteOptionsResult< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> = Omit< + DefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + 'queryKey' +> & { + queryKey: DataTag, TError> +} + export function infiniteQueryOptions< TQueryFnData, TError = DefaultError, @@ -86,15 +143,13 @@ export function infiniteQueryOptions< TQueryKey, TPageParam >, -): DefinedInitialDataInfiniteOptions< +): DefinedInitialDataInfiniteOptionsResult< TQueryFnData, TError, TData, TQueryKey, TPageParam -> & { - queryKey: DataTag, TError> -} +> export function infiniteQueryOptions< TQueryFnData, @@ -110,15 +165,13 @@ export function infiniteQueryOptions< TQueryKey, TPageParam >, -): UnusedSkipTokenInfiniteOptions< +): UnusedSkipTokenInfiniteOptionsResult< TQueryFnData, TError, TData, TQueryKey, TPageParam -> & { - queryKey: DataTag, TError> -} +> export function infiniteQueryOptions< TQueryFnData, @@ -134,15 +187,13 @@ export function infiniteQueryOptions< TQueryKey, TPageParam >, -): UndefinedInitialDataInfiniteOptions< +): UndefinedInitialDataInfiniteOptionsResult< TQueryFnData, TError, TData, TQueryKey, TPageParam -> & { - queryKey: DataTag, TError> -} +> export function infiniteQueryOptions(options: unknown) { return options diff --git a/packages/react-query/src/queryOptions.ts b/packages/react-query/src/queryOptions.ts index 644ac26788..aa1052a460 100644 --- a/packages/react-query/src/queryOptions.ts +++ b/packages/react-query/src/queryOptions.ts @@ -22,6 +22,18 @@ export type UndefinedInitialDataOptions< | NonUndefinedGuard } +export type UndefinedInitialDataOptionsResult< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = Omit< + UndefinedInitialDataOptions, + 'queryKey' +> & { + queryKey: DataTag +} + export type UnusedSkipTokenOptions< TQueryFnData = unknown, TError = DefaultError, @@ -37,6 +49,18 @@ export type UnusedSkipTokenOptions< > } +export type UnusedSkipTokenOptionsResult< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = Omit< + UnusedSkipTokenOptions, + 'queryKey' +> & { + queryKey: DataTag +} + export type DefinedInitialDataOptions< TQueryFnData = unknown, TError = DefaultError, @@ -49,6 +73,18 @@ export type DefinedInitialDataOptions< queryFn?: QueryFunction } +export type DefinedInitialDataOptionsResult< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = Omit< + DefinedInitialDataOptions, + 'queryKey' +> & { + queryKey: DataTag +} + export function queryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -56,9 +92,7 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: DefinedInitialDataOptions, -): DefinedInitialDataOptions & { - queryKey: DataTag -} +): DefinedInitialDataOptionsResult export function queryOptions< TQueryFnData = unknown, @@ -67,9 +101,7 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: UnusedSkipTokenOptions, -): UnusedSkipTokenOptions & { - queryKey: DataTag -} +): UnusedSkipTokenOptionsResult export function queryOptions< TQueryFnData = unknown, @@ -78,9 +110,7 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: UndefinedInitialDataOptions, -): UndefinedInitialDataOptions & { - queryKey: DataTag -} +): UndefinedInitialDataOptionsResult export function queryOptions(options: unknown) { return options diff --git a/packages/react-query/src/useQueries.ts b/packages/react-query/src/useQueries.ts index 6eabef4060..8c319fb17c 100644 --- a/packages/react-query/src/useQueries.ts +++ b/packages/react-query/src/useQueries.ts @@ -82,15 +82,21 @@ type GetUseQueryOptionsForUseQueries = queryFn?: | QueryFunction | SkipTokenForUseQueries - select?: (data: any) => infer TData throwOnError?: ThrowOnError } - ? UseQueryOptionsForUseQueries< - TQueryFnData, - unknown extends TError ? DefaultError : TError, - unknown extends TData ? TQueryFnData : TData, - TQueryKey - > + ? T extends { select?: (data: TQueryFnData) => infer TData } + ? UseQueryOptionsForUseQueries< + TQueryFnData, + unknown extends TError ? DefaultError : TError, + unknown extends TData ? TQueryFnData : TData, + TQueryKey + > + : UseQueryOptionsForUseQueries< + TQueryFnData, + unknown extends TError ? DefaultError : TError, + TQueryFnData, + TQueryKey + > : // Fallback UseQueryOptionsForUseQueries @@ -131,14 +137,19 @@ type GetUseQueryResult = queryFn?: | QueryFunction | SkipTokenForUseQueries - select?: (data: any) => infer TData throwOnError?: ThrowOnError } - ? GetDefinedOrUndefinedQueryResult< - T, - unknown extends TData ? TQueryFnData : TData, - unknown extends TError ? DefaultError : TError - > + ? T extends { select?: (data: TQueryFnData) => infer TData } + ? GetDefinedOrUndefinedQueryResult< + T, + unknown extends TData ? TQueryFnData : TData, + unknown extends TError ? DefaultError : TError + > + : GetDefinedOrUndefinedQueryResult< + T, + TQueryFnData, + unknown extends TError ? DefaultError : TError + > : // Fallback UseQueryResult diff --git a/packages/react-query/src/useSuspenseQueries.ts b/packages/react-query/src/useSuspenseQueries.ts index f014095d01..b60e3dd121 100644 --- a/packages/react-query/src/useSuspenseQueries.ts +++ b/packages/react-query/src/useSuspenseQueries.ts @@ -40,29 +40,23 @@ type GetUseSuspenseQueryOptions = queryFn?: | QueryFunction | SkipTokenForUseQueries - select?: (data: any) => infer TData throwOnError?: ThrowOnError } - ? UseSuspenseQueryOptions< - TQueryFnData, - TError, - TData, - TQueryKey - > - : T extends { - queryFn?: - | QueryFunction - | SkipTokenForUseQueries - throwOnError?: ThrowOnError - } + ? T extends { select?: (data: TQueryFnData) => infer TData } ? UseSuspenseQueryOptions< + TQueryFnData, + TError, + TData, + TQueryKey + > + : UseSuspenseQueryOptions< TQueryFnData, TError, TQueryFnData, TQueryKey > - : // Fallback - UseSuspenseQueryOptions + : // Fallback + UseSuspenseQueryOptions type GetUseSuspenseQueryResult = // Part 1: responsible for mapping explicit type parameter to function result, if object @@ -84,25 +78,19 @@ type GetUseSuspenseQueryResult = queryFn?: | QueryFunction | SkipTokenForUseQueries - select?: (data: any) => infer TData throwOnError?: ThrowOnError } - ? UseSuspenseQueryResult< - unknown extends TData ? TQueryFnData : TData, - unknown extends TError ? DefaultError : TError - > - : T extends { - queryFn?: - | QueryFunction - | SkipTokenForUseQueries - throwOnError?: ThrowOnError - } + ? T extends { select?: (data: TQueryFnData) => infer TData } ? UseSuspenseQueryResult< + unknown extends TData ? TQueryFnData : TData, + unknown extends TError ? DefaultError : TError + > + : UseSuspenseQueryResult< TQueryFnData, unknown extends TError ? DefaultError : TError > - : // Fallback - UseSuspenseQueryResult + : // Fallback + UseSuspenseQueryResult /** * SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param