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

Add types for QueryFilters which flow down to Query<> and QueryKey/DataTag types #8332

Merged
merged 8 commits into from
Nov 27, 2024
Merged
45 changes: 45 additions & 0 deletions packages/query-core/src/__tests__/utils.test-d.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expectTypeOf, it } from 'vitest'
import { QueryClient } from '../queryClient'
import type { QueryFilters } from '../utils'
import { DataTag } from '../types'

describe('QueryFilters', () => {
it('should be typed if generics are passed', () => {
type TData = { a: number; b: string }
type TError = { message: string }

const a: QueryFilters<TData, TError> = {
predicate(query) {
expectTypeOf(query.setData({a: 1, b: '1'})).toEqualTypeOf<TData>()
return true
},
queryKey: ['key'] as DataTag<undefined, TData>
}

const queryClient = new QueryClient()

const data = queryClient.getQueryData(a.queryKey!)
expectTypeOf(data).toEqualTypeOf<TData | undefined>()

const error = queryClient.getQueryState(a.queryKey!)?.error
expectTypeOf(error).toEqualTypeOf<Error | null | undefined>() // maybe one day this can return TError
})

it('should be loose typed if generics are defaults', () => {
const a: QueryFilters = {
predicate(query) {
expectTypeOf(query.setData({a: 1, b: '1'})).toEqualTypeOf<unknown>()
return true
},
queryKey: ['key']
}

const queryClient = new QueryClient()

const data = queryClient.getQueryData(a.queryKey!)
expectTypeOf(data).toEqualTypeOf<unknown>()

const error = queryClient.getQueryState(a.queryKey!)?.error
expectTypeOf(error).toEqualTypeOf<Error | null | undefined>()
})
})
14 changes: 12 additions & 2 deletions packages/query-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,11 +534,21 @@ export interface RefetchOptions extends ResultOptions {
cancelRefetch?: boolean
}

export interface InvalidateQueryFilters extends QueryFilters {
export interface InvalidateQueryFilters<
TQueryFnData = unknown,
TError = Error,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> extends QueryFilters<TQueryFnData, TError, TData, TQueryKey> {
refetchType?: QueryTypeFilter | 'none'
}

export interface RefetchQueryFilters extends QueryFilters {}
export interface RefetchQueryFilters<
TQueryFnData = unknown,
TError = Error,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> extends QueryFilters<TQueryFnData, TError, TData, TQueryKey> {}

export interface InvalidateOptions extends RefetchOptions {}
export interface ResetOptions extends RefetchOptions {}
Expand Down
14 changes: 11 additions & 3 deletions packages/query-core/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
DataTag,
DefaultError,
Enabled,
FetchStatus,
Expand All @@ -14,7 +15,12 @@ import type { FetchOptions, Query } from './query'

// TYPES

export interface QueryFilters {
export interface QueryFilters<
TQueryFnData = unknown,
TError = Error,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> {
/**
* Filter to active queries, inactive queries or all queries
*/
Expand All @@ -26,11 +32,13 @@ export interface QueryFilters {
/**
* Include queries matching this predicate function
*/
predicate?: (query: Query) => boolean
predicate?: (query: Query<TQueryFnData, TError, TData, TQueryKey>) => boolean
/**
* Include queries matching this query key
*/
queryKey?: QueryKey
queryKey?: unknown extends TQueryFnData
? QueryKey
: QueryKey & DataTag<unknown, TQueryFnData>
/**
* Include or exclude stale queries
*/
Expand Down
Loading