Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vue-query): useQueries type inference #7416

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 29 additions & 32 deletions packages/vue-query/src/useQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import type {
DefaultError,
DefinedQueryObserverResult,
QueriesObserverOptions,
QueriesPlaceholderDataFunction,
QueryFunction,
QueryKey,
QueryObserverResult,
SkipToken,
ThrowOnError,
} from '@tanstack/query-core'
import type { UseQueryOptions } from './useQuery'
import type { QueryClient } from './queryClient'
import type { DeepUnwrapRef, DistributiveOmit, MaybeRefDeep } from './types'
import type { DeepUnwrapRef, MaybeRefDeep } from './types'

// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
// `placeholderData` function does not have a parameter
Expand All @@ -32,17 +32,12 @@ type UseQueryOptionsForUseQueries<
TError = unknown,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> = DistributiveOmit<
UseQueryOptions<TQueryFnData, TError, TData, unknown, TQueryKey>,
'placeholderData'
> & {
placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>
}
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>

// Avoid TS depth-limit error in case of large array literal
type MAXIMUM_DEPTH = 20

type GetOptions<T> =
type GetUseQueryOptionsForUseQueries<T> =
// Part 1: if UseQueryOptions are already being sent through, then just return T
T extends UseQueryOptions
? DeepUnwrapRef<T>
Expand All @@ -66,10 +61,9 @@ type GetOptions<T> =
? UseQueryOptionsForUseQueries<TQueryFnData>
: // Part 4: responsible for inferring and enforcing type if no explicit parameter was provided
T extends {
queryFn?: QueryFunction<
infer TQueryFnData,
infer TQueryKey
>
queryFn?:
| QueryFunction<infer TQueryFnData, infer TQueryKey>
| SkipToken
select?: (data: any) => infer TData
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
Expand All @@ -80,10 +74,9 @@ type GetOptions<T> =
TQueryKey
>
: T extends {
queryFn?: QueryFunction<
infer TQueryFnData,
infer TQueryKey
>
queryFn?:
| QueryFunction<infer TQueryFnData, infer TQueryKey>
| SkipToken
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
? UseQueryOptionsForUseQueries<
Expand Down Expand Up @@ -112,7 +105,7 @@ type GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {
: QueryObserverResult<TData, TError>
: QueryObserverResult<TData, TError>

type GetResults<T> =
type GetUseQueryResult<T> =
// Part 1: if using UseQueryOptions then the types are already set
T extends UseQueryOptions<
infer TQueryFnData,
Expand Down Expand Up @@ -142,7 +135,9 @@ type GetResults<T> =
? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>
: // Part 4: responsible for mapping inferred type to results, if no explicit parameter was provided
T extends {
queryFn?: QueryFunction<infer TQueryFnData, any>
queryFn?:
| QueryFunction<infer TQueryFnData, any>
| SkipToken
select?: (data: any) => infer TData
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
Expand All @@ -152,7 +147,9 @@ type GetResults<T> =
unknown extends TError ? DefaultError : TError
>
: T extends {
queryFn?: QueryFunction<infer TQueryFnData, any>
queryFn?:
| QueryFunction<infer TQueryFnData, any>
| SkipToken
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
? GetDefinedOrUndefinedQueryResult<
Expand All @@ -168,21 +165,21 @@ type GetResults<T> =
*/
export type UseQueriesOptions<
T extends Array<any>,
TResult extends Array<any> = [],
TResults extends Array<any> = [],
TDepth extends ReadonlyArray<number> = [],
> = TDepth['length'] extends MAXIMUM_DEPTH
? Array<UseQueryOptionsForUseQueries>
: T extends []
? []
: T extends [infer Head]
? [...TResult, GetOptions<Head>]
: T extends [infer Head, ...infer Tail]
? [...TResults, GetUseQueryOptionsForUseQueries<Head>]
: T extends [infer Head, ...infer Tails]
? UseQueriesOptions<
[...Tail],
[...TResult, GetOptions<Head>],
[...Tails],
[...TResults, GetUseQueryOptionsForUseQueries<Head>],
[...TDepth, 1]
>
: Readonly<unknown> extends T
: ReadonlyArray<unknown> extends T
? T
: // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
// use this to infer the param types in the case of Array.map() argument
Expand Down Expand Up @@ -210,18 +207,18 @@ export type UseQueriesOptions<
*/
export type UseQueriesResults<
T extends Array<any>,
TResult extends Array<any> = [],
TResults extends Array<any> = [],
TDepth extends ReadonlyArray<number> = [],
> = TDepth['length'] extends MAXIMUM_DEPTH
? Array<QueryObserverResult>
: T extends []
? []
: T extends [infer Head]
? [...TResult, GetResults<Head>]
: T extends [infer Head, ...infer Tail]
? [...TResults, GetUseQueryResult<Head>]
: T extends [infer Head, ...infer Tails]
? UseQueriesResults<
[...Tail],
[...TResult, GetResults<Head>],
[...Tails],
[...TResults, GetUseQueryResult<Head>],
[...TDepth, 1]
>
: T extends Array<
Expand All @@ -236,7 +233,7 @@ export type UseQueriesResults<
Array<
QueryObserverResult<
unknown extends TData ? TQueryFnData : TData,
TError
unknown extends TError ? DefaultError : TError
>
>
: // Fallback
Expand Down