Skip to content

Commit

Permalink
refactor(react-query): improve type inference for useSuspenseQueries …
Browse files Browse the repository at this point in the history
…with skipToken (#7564)

Co-authored-by: Dominik Dorfmeister <[email protected]>
  • Loading branch information
gwansikk and TkDodo committed Jun 16, 2024
1 parent 8d69ef4 commit 77a7b28
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
22 changes: 20 additions & 2 deletions packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expectTypeOf, it } from 'vitest'
import { useSuspenseQueries } from '..'
import { skipToken, useSuspenseQueries } from '..'
import { queryOptions } from '../queryOptions'
import type { OmitKeyof } from '..'
import type { UseQueryOptions } from '../types'
import type { UseQueryOptions, UseSuspenseQueryResult } from '../types'

describe('UseSuspenseQueries config object overload', () => {
it('TData should always be defined', () => {
Expand Down Expand Up @@ -113,4 +113,22 @@ describe('UseSuspenseQueries config object overload', () => {
expectTypeOf(data).toEqualTypeOf<Data>()
})
})

it('TData should have correct type when conditional skipToken is passed', () => {
const queryResults = useSuspenseQueries({
queries: [
{
queryKey: ['withSkipToken'],
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
},
],
})

const firstResult = queryResults[0]

expectTypeOf(firstResult).toEqualTypeOf<
UseSuspenseQueryResult<number, Error>
>()
expectTypeOf(firstResult.data).toEqualTypeOf<number>()
})
})
14 changes: 9 additions & 5 deletions packages/react-query/src/useSuspenseQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import type {
DefaultError,
QueryClient,
QueryFunction,
SkipToken,
ThrowOnError,
} from '@tanstack/query-core'

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

// Widen the type of the symbol to enable type inference even if skipToken is not immutable.
type SkipTokenForUseQueries = symbol

type GetUseSuspenseQueryOptions<T> =
// Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }
T extends {
Expand All @@ -36,7 +38,7 @@ type GetUseSuspenseQueryOptions<T> =
T extends {
queryFn?:
| QueryFunction<infer TQueryFnData, infer TQueryKey>
| SkipToken
| SkipTokenForUseQueries
select?: (data: any) => infer TData
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
Expand All @@ -49,7 +51,7 @@ type GetUseSuspenseQueryOptions<T> =
: T extends {
queryFn?:
| QueryFunction<infer TQueryFnData, infer TQueryKey>
| SkipToken
| SkipTokenForUseQueries
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
? UseSuspenseQueryOptions<
Expand Down Expand Up @@ -78,7 +80,9 @@ type GetUseSuspenseQueryResult<T> =
? UseSuspenseQueryResult<TQueryFnData>
: // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided
T extends {
queryFn?: QueryFunction<infer TQueryFnData, any> | SkipToken
queryFn?:
| QueryFunction<infer TQueryFnData, any>
| SkipTokenForUseQueries
select?: (data: any) => infer TData
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
Expand All @@ -89,7 +93,7 @@ type GetUseSuspenseQueryResult<T> =
: T extends {
queryFn?:
| QueryFunction<infer TQueryFnData, any>
| SkipToken
| SkipTokenForUseQueries
throwOnError?: ThrowOnError<any, infer TError, any, any>
}
? UseSuspenseQueryResult<
Expand Down

0 comments on commit 77a7b28

Please sign in to comment.