Skip to content

Commit 7bfe047

Browse files
committed
fix(vue-query/queryOptions): accept the same options as useQuery
1 parent d6798b5 commit 7bfe047

11 files changed

Lines changed: 145 additions & 204 deletions

packages/vue-query/src/__tests__/queryOptions.test-d.ts

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assertType, describe, expectTypeOf, it } from 'vitest'
22
import { computed, reactive, ref } from 'vue-demi'
3-
import { dataTagSymbol } from '@tanstack/query-core'
3+
import { dataTagSymbol, skipToken } from '@tanstack/query-core'
44
import { queryKey } from '@tanstack/query-test-utils'
55
import { QueryClient } from '../queryClient'
66
import { queryOptions } from '../queryOptions'
@@ -11,9 +11,9 @@ describe('queryOptions', () => {
1111
const key = queryKey()
1212
assertType(
1313
queryOptions({
14-
// @ts-expect-error this is a good error, because stallTime does not exist!
1514
queryKey: key,
1615
queryFn: () => Promise.resolve(5),
16+
// @ts-expect-error this is a good error, because stallTime does not exist!
1717
stallTime: 1000,
1818
}),
1919
)
@@ -231,27 +231,45 @@ describe('queryOptions', () => {
231231
expectTypeOf(data).toEqualTypeOf<number>()
232232
})
233233

234-
it('should allow accessing queryFn and other properties on the returned options object', () => {
234+
it('should keep the tagged queryKey accessible and be spreadable into useQuery', () => {
235235
const options = queryOptions({
236236
queryKey: queryKey(),
237-
queryFn: () => Promise.resolve([]),
237+
queryFn: () => Promise.resolve(5),
238238
})
239239

240-
expectTypeOf(options.queryFn).not.toBeUndefined()
241240
expectTypeOf(options.queryKey).not.toBeUndefined()
242-
expectTypeOf(options.staleTime).not.toBeUndefined()
241+
242+
const { data } = reactive(
243+
useQuery({
244+
...options,
245+
select: (d) => d.toString(),
246+
}),
247+
)
248+
expectTypeOf(data).toEqualTypeOf<string | undefined>()
243249
})
244250

245-
it('should allow accessing queryFn and other properties on the returned options when used with getter', () => {
251+
it('should allow a getter returning options to be passed to useQuery', () => {
246252
const options = queryOptions(() => ({
247253
queryKey: queryKey(),
248-
queryFn: () => Promise.resolve([]),
254+
queryFn: () => Promise.resolve(5),
249255
}))
250256

251-
const resolvedGetter = options()
257+
const { data } = reactive(useQuery(options))
258+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
259+
})
260+
261+
it('should allow a computed queryFn returning skipToken, matching useQuery', () => {
262+
const enabled = ref(false)
263+
264+
const options = queryOptions({
265+
queryKey: queryKey(),
266+
queryFn: computed(() =>
267+
enabled.value ? () => Promise.resolve(5) : skipToken,
268+
),
269+
})
252270

253-
expectTypeOf(resolvedGetter.queryFn).not.toBeUndefined()
254-
expectTypeOf(resolvedGetter.queryKey).not.toBeUndefined()
271+
const { data } = reactive(useQuery(options))
272+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
255273
})
256274

257275
it('should allow computed ref as enabled property', () => {
@@ -322,14 +340,15 @@ describe('queryOptions', () => {
322340
expectTypeOf(options.queryKey).not.toBeUndefined()
323341
})
324342

325-
it('should allow getter function as queryKey', () => {
343+
it('should not allow a per-field getter as queryKey, matching useQuery (use computed/ref, or a getter for the whole options)', () => {
326344
const id = ref<string | null>('1')
327345

328-
const options = queryOptions({
329-
queryKey: () => ['foo', id.value] as const,
330-
queryFn: () => Promise.resolve({ id: '1' }),
331-
})
332-
333-
expectTypeOf(options.queryKey).not.toBeUndefined()
346+
assertType(
347+
queryOptions({
348+
// @ts-expect-error queryKey must be a plain key / ref / computed, not a per-field getter
349+
queryKey: () => ['foo', id.value] as const,
350+
queryFn: () => Promise.resolve({ id: '1' }),
351+
}),
352+
)
334353
})
335354
})

packages/vue-query/src/__tests__/queryOptions.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { describe, expect, it } from 'vitest'
22
import { queryKey } from '@tanstack/query-test-utils'
33
import { queryOptions } from '../queryOptions'
4-
import type { QueryOptions } from '../queryOptions'
4+
import type { UseQueryOptions } from '../queryOptions'
55

66
describe('queryOptions', () => {
77
it('should return the object received as a parameter without any modification.', () => {
8-
const object: QueryOptions = {
8+
const object: UseQueryOptions = {
99
queryKey: queryKey(),
1010
queryFn: () => Promise.resolve(5),
1111
} as const

packages/vue-query/src/__tests__/useQueries.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { queryKey } from '@tanstack/query-test-utils'
44
import { skipToken, useQueries } from '..'
55
import { queryOptions } from '../queryOptions'
66
import type { OmitKeyof, QueryObserverResult } from '..'
7-
import type { UseQueryOptions } from '../useQuery'
7+
import type { UseQueryOptions } from '../queryOptions'
88

99
describe('UseQueries config object overload', () => {
1010
it('TData should always be defined when initialData is provided as an object', () => {

packages/vue-query/src/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export { VueQueryPlugin } from './vueQueryPlugin'
66
export { QueryClient } from './queryClient'
77
export { QueryCache } from './queryCache'
88
export { queryOptions } from './queryOptions'
9-
export { type QueryOptions } from './queryOptions'
109
export { infiniteQueryOptions } from './infiniteQueryOptions'
1110
export type {
1211
DefinedInitialDataInfiniteOptions,
@@ -26,17 +25,14 @@ export { VUE_QUERY_CLIENT } from './utils'
2625

2726
export type { UsePrefetchQueryOptions } from './usePrefetchQuery'
2827
export type { UsePrefetchInfiniteQueryOptions } from './usePrefetchInfiniteQuery'
28+
export type { UseQueryReturnType, UseQueryDefinedReturnType } from './useQuery'
2929
export type {
3030
UseQueryOptions,
31-
UseQueryReturnType,
32-
UseQueryDefinedReturnType,
3331
UndefinedInitialQueryOptions,
3432
DefinedInitialQueryOptions,
35-
} from './useQuery'
36-
export type {
37-
UseInfiniteQueryOptions,
38-
UseInfiniteQueryReturnType,
39-
} from './useInfiniteQuery'
33+
} from './queryOptions'
34+
export type { UseInfiniteQueryReturnType } from './useInfiniteQuery'
35+
export type { UseInfiniteQueryOptions } from './infiniteQueryOptions'
4036
export type { UseMutationOptions, UseMutationReturnType } from './useMutation'
4137
export type { MutationOptions } from './types'
4238
export type { UseQueriesOptions, UseQueriesResults } from './useQueries'

packages/vue-query/src/infiniteQueryOptions.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,54 @@ import type {
22
DataTag,
33
DefaultError,
44
InfiniteData,
5+
InfiniteQueryObserverOptions,
56
NonUndefinedGuard,
67
QueryKey,
78
} from '@tanstack/query-core'
8-
import type { UseInfiniteQueryOptions } from './useInfiniteQuery'
9+
10+
import type {
11+
DeepUnwrapRef,
12+
MaybeRef,
13+
MaybeRefDeep,
14+
MaybeRefOrGetter,
15+
ShallowOption,
16+
} from './types'
17+
18+
export type UseInfiniteQueryOptions<
19+
TQueryFnData = unknown,
20+
TError = DefaultError,
21+
TData = TQueryFnData,
22+
TQueryKey extends QueryKey = QueryKey,
23+
TPageParam = unknown,
24+
> = MaybeRef<
25+
{
26+
[Property in keyof InfiniteQueryObserverOptions<
27+
TQueryFnData,
28+
TError,
29+
TData,
30+
TQueryKey,
31+
TPageParam
32+
>]: Property extends 'enabled'
33+
? MaybeRefOrGetter<
34+
InfiniteQueryObserverOptions<
35+
TQueryFnData,
36+
TError,
37+
TData,
38+
DeepUnwrapRef<TQueryKey>,
39+
TPageParam
40+
>[Property]
41+
>
42+
: MaybeRefDeep<
43+
InfiniteQueryObserverOptions<
44+
TQueryFnData,
45+
TError,
46+
TData,
47+
DeepUnwrapRef<TQueryKey>,
48+
TPageParam
49+
>[Property]
50+
>
51+
} & ShallowOption
52+
>
953

1054
export type UndefinedInitialDataInfiniteOptions<
1155
TQueryFnData,

packages/vue-query/src/queryClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { QueryClient as QC } from '@tanstack/query-core'
33
import { cloneDeepUnref } from './utils'
44
import { QueryCache } from './queryCache'
55
import { MutationCache } from './mutationCache'
6-
import type { UseQueryOptions } from './useQuery'
6+
import type { UseQueryOptions } from './queryOptions'
77
import type { Ref } from 'vue-demi'
88
import type { MaybeRefDeep, NoUnknown, QueryClientConfig } from './types'
99
import type {

packages/vue-query/src/queryOptions.ts

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { DeepUnwrapRef, MaybeRefOrGetter, ShallowOption } from './types'
21
import type {
32
DataTag,
43
DefaultError,
@@ -9,45 +8,55 @@ import type {
98
QueryObserverOptions,
109
} from '@tanstack/query-core'
1110

12-
export type QueryOptions<
11+
import type {
12+
DeepUnwrapRef,
13+
MaybeRef,
14+
MaybeRefDeep,
15+
MaybeRefOrGetter,
16+
ShallowOption,
17+
} from './types'
18+
19+
export type UseQueryOptions<
1320
TQueryFnData = unknown,
1421
TError = DefaultError,
1522
TData = TQueryFnData,
1623
TQueryData = TQueryFnData,
1724
TQueryKey extends QueryKey = QueryKey,
18-
> = {
19-
[Property in keyof QueryObserverOptions<
20-
TQueryFnData,
21-
TError,
22-
TData,
23-
TQueryData,
24-
TQueryKey
25-
>]: Property extends 'enabled'
26-
?
27-
| MaybeRefOrGetter<boolean | undefined>
28-
| (() => QueryBooleanOption<
25+
> = MaybeRef<
26+
{
27+
[Property in keyof QueryObserverOptions<
28+
TQueryFnData,
29+
TError,
30+
TData,
31+
TQueryData,
32+
TQueryKey
33+
>]: Property extends 'enabled'
34+
?
35+
| MaybeRefOrGetter<boolean | undefined>
36+
| (() => QueryBooleanOption<
37+
TQueryFnData,
38+
TError,
39+
TQueryData,
40+
DeepUnwrapRef<TQueryKey>
41+
>)
42+
: MaybeRefDeep<
43+
QueryObserverOptions<
2944
TQueryFnData,
3045
TError,
46+
TData,
3147
TQueryData,
3248
DeepUnwrapRef<TQueryKey>
33-
>)
34-
: Property extends 'queryKey'
35-
? MaybeRefOrGetter<TQueryKey>
36-
: QueryObserverOptions<
37-
TQueryFnData,
38-
TError,
39-
TData,
40-
TQueryData,
41-
DeepUnwrapRef<TQueryKey>
42-
>[Property]
43-
} & ShallowOption
49+
>[Property]
50+
>
51+
} & ShallowOption
52+
>
4453

4554
export type UndefinedInitialQueryOptions<
4655
TQueryFnData = unknown,
4756
TError = DefaultError,
4857
TData = TQueryFnData,
4958
TQueryKey extends QueryKey = QueryKey,
50-
> = QueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
59+
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
5160
initialData?:
5261
| undefined
5362
| InitialDataFunction<NonUndefinedGuard<TQueryFnData>>
@@ -59,7 +68,7 @@ export type DefinedInitialQueryOptions<
5968
TError = DefaultError,
6069
TData = TQueryFnData,
6170
TQueryKey extends QueryKey = QueryKey,
62-
> = QueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
71+
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
6372
initialData:
6473
| NonUndefinedGuard<TQueryFnData>
6574
| (() => NonUndefinedGuard<TQueryFnData>)
@@ -76,22 +85,6 @@ export function queryOptions<
7685
queryKey: DataTag<TQueryKey, TQueryFnData, TError>
7786
}
7887

79-
export function queryOptions<
80-
TQueryFnData = unknown,
81-
TError = DefaultError,
82-
TData = TQueryFnData,
83-
TQueryKey extends QueryKey = QueryKey,
84-
>(
85-
options: () => DefinedInitialQueryOptions<
86-
TQueryFnData,
87-
TError,
88-
TData,
89-
TQueryKey
90-
>,
91-
): () => DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
92-
queryKey: DataTag<TQueryKey, TQueryFnData, TError>
93-
}
94-
9588
export function queryOptions<
9689
TQueryFnData = unknown,
9790
TError = DefaultError,
@@ -109,17 +102,11 @@ export function queryOptions<
109102
TData = TQueryFnData,
110103
TQueryKey extends QueryKey = QueryKey,
111104
>(
112-
options: () => UndefinedInitialQueryOptions<
113-
TQueryFnData,
114-
TError,
115-
TData,
116-
TQueryKey
105+
options: MaybeRefOrGetter<
106+
UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>
117107
>,
118-
): () => UndefinedInitialQueryOptions<
119-
TQueryFnData,
120-
TError,
121-
TData,
122-
TQueryKey
108+
): MaybeRefOrGetter<
109+
UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>
123110
> & {
124111
queryKey: DataTag<TQueryKey, TQueryFnData, TError>
125112
}

packages/vue-query/src/useBaseQuery.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import type {
2020
QueryObserverResult,
2121
} from '@tanstack/query-core'
2222
import type { QueryClient } from './queryClient'
23-
import type { UseQueryOptions } from './useQuery'
24-
import type { UseInfiniteQueryOptions } from './useInfiniteQuery'
2523
import type { MaybeRefOrGetter } from './types'
24+
import type { UseQueryOptions } from './queryOptions'
25+
import type { UseInfiniteQueryOptions } from './infiniteQueryOptions'
2626

2727
export type UseBaseQueryReturnType<
2828
TData,

0 commit comments

Comments
 (0)