@tanstack/vue-query 5.40.0 → 5.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/legacy/index.cjs +3 -0
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +1 -0
- package/build/legacy/index.d.ts +1 -0
- package/build/legacy/index.js +2 -0
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs +33 -0
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -0
- package/build/legacy/infiniteQueryOptions.d.cts +21 -0
- package/build/legacy/infiniteQueryOptions.d.ts +21 -0
- package/build/legacy/infiniteQueryOptions.js +8 -0
- package/build/legacy/infiniteQueryOptions.js.map +1 -0
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +9 -14
- package/build/legacy/useQueries.d.ts +9 -14
- package/build/legacy/useQueries.js.map +1 -1
- package/build/modern/index.cjs +3 -0
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +1 -0
- package/build/modern/index.d.ts +1 -0
- package/build/modern/index.js +2 -0
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs +33 -0
- package/build/modern/infiniteQueryOptions.cjs.map +1 -0
- package/build/modern/infiniteQueryOptions.d.cts +21 -0
- package/build/modern/infiniteQueryOptions.d.ts +21 -0
- package/build/modern/infiniteQueryOptions.js +8 -0
- package/build/modern/infiniteQueryOptions.js.map +1 -0
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +9 -14
- package/build/modern/useQueries.d.ts +9 -14
- package/build/modern/useQueries.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/infiniteQueryOptions.test-d.ts +111 -0
- package/src/__tests__/queryClient.test-d.ts +132 -0
- package/src/__tests__/queryClient.test.ts +17 -0
- package/src/__tests__/queryOptions.test-d.ts +125 -0
- package/src/__tests__/test-utils.ts +0 -10
- package/src/__tests__/useInfiniteQuery.test-d.tsx +84 -0
- package/src/__tests__/useInfiniteQuery.test.ts +32 -0
- package/src/__tests__/useMutation.test-d.tsx +74 -0
- package/src/__tests__/useQueries.test-d.ts +145 -0
- package/src/__tests__/useQuery.test-d.ts +228 -0
- package/src/index.ts +5 -0
- package/src/infiniteQueryOptions.ts +94 -0
- package/src/useQueries.ts +18 -36
- package/src/__tests__/queryClient.type.test.ts +0 -174
- package/src/__tests__/queryOptions.types.test.ts +0 -170
- package/src/__tests__/useInfiniteQuery.types.test.tsx +0 -106
- package/src/__tests__/useMutation.types.test.tsx +0 -98
- package/src/__tests__/useQueries.types.test.ts +0 -176
- package/src/__tests__/useQuery.types.test.ts +0 -282
|
@@ -2,6 +2,7 @@ import { describe, expect, test, vi } from 'vitest'
|
|
|
2
2
|
import { ref } from 'vue-demi'
|
|
3
3
|
import { QueryClient as QueryClientOrigin } from '@tanstack/query-core'
|
|
4
4
|
import { QueryClient } from '../queryClient'
|
|
5
|
+
import { infiniteQueryOptions } from '../infiniteQueryOptions'
|
|
5
6
|
import { flushPromises } from './test-utils'
|
|
6
7
|
|
|
7
8
|
vi.mock('@tanstack/query-core')
|
|
@@ -264,6 +265,22 @@ describe('QueryCache', () => {
|
|
|
264
265
|
initialPageParam: 0,
|
|
265
266
|
})
|
|
266
267
|
|
|
268
|
+
expect(QueryClientOrigin.prototype.fetchInfiniteQuery).toBeCalledWith({
|
|
269
|
+
initialPageParam: 0,
|
|
270
|
+
queryKey: queryKeyUnref,
|
|
271
|
+
})
|
|
272
|
+
})
|
|
273
|
+
test('should properly unwrap parameter using infiniteQueryOptions with unref', async () => {
|
|
274
|
+
const queryClient = new QueryClient()
|
|
275
|
+
|
|
276
|
+
const options = infiniteQueryOptions({
|
|
277
|
+
queryKey: queryKeyUnref,
|
|
278
|
+
initialPageParam: 0,
|
|
279
|
+
getNextPageParam: () => 12,
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
queryClient.fetchInfiniteQuery(options)
|
|
283
|
+
|
|
267
284
|
expect(QueryClientOrigin.prototype.fetchInfiniteQuery).toBeCalledWith({
|
|
268
285
|
initialPageParam: 0,
|
|
269
286
|
queryKey: queryKeyUnref,
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { reactive, ref } from 'vue-demi'
|
|
3
|
+
import { dataTagSymbol } from '@tanstack/query-core'
|
|
4
|
+
import { QueryClient } from '../queryClient'
|
|
5
|
+
import { queryOptions } from '../queryOptions'
|
|
6
|
+
import { useQuery } from '../useQuery'
|
|
7
|
+
|
|
8
|
+
describe('queryOptions', () => {
|
|
9
|
+
it('should not allow excess properties', () => {
|
|
10
|
+
queryOptions({
|
|
11
|
+
queryKey: ['key'],
|
|
12
|
+
queryFn: () => Promise.resolve(5),
|
|
13
|
+
// @ts-expect-error this is a good error, because stallTime does not exist!
|
|
14
|
+
stallTime: 1000,
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
it('should infer types for callbacks', () => {
|
|
18
|
+
queryOptions({
|
|
19
|
+
queryKey: ['key'],
|
|
20
|
+
queryFn: () => Promise.resolve(5),
|
|
21
|
+
staleTime: 1000,
|
|
22
|
+
select: (data) => {
|
|
23
|
+
expectTypeOf(data).toEqualTypeOf<number>()
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
it('should work when passed to useQuery', () => {
|
|
28
|
+
const options = queryOptions({
|
|
29
|
+
queryKey: ['key'],
|
|
30
|
+
queryFn: () => Promise.resolve(5),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const { data } = reactive(useQuery(options))
|
|
34
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
35
|
+
})
|
|
36
|
+
it('should tag the queryKey with the result type of the QueryFn', () => {
|
|
37
|
+
const { queryKey } = queryOptions({
|
|
38
|
+
queryKey: ['key'],
|
|
39
|
+
queryFn: () => Promise.resolve(5),
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
|
|
43
|
+
})
|
|
44
|
+
it('should tag the queryKey even if no promise is returned', () => {
|
|
45
|
+
const { queryKey } = queryOptions({
|
|
46
|
+
queryKey: ['key'],
|
|
47
|
+
queryFn: () => 5,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
|
|
51
|
+
})
|
|
52
|
+
it('should tag the queryKey with unknown if there is no queryFn', () => {
|
|
53
|
+
const { queryKey } = queryOptions({
|
|
54
|
+
queryKey: ['key'],
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<unknown>()
|
|
58
|
+
})
|
|
59
|
+
it('should tag the queryKey with the result type of the QueryFn if select is used', () => {
|
|
60
|
+
const { queryKey } = queryOptions({
|
|
61
|
+
queryKey: ['key'],
|
|
62
|
+
queryFn: () => Promise.resolve(5),
|
|
63
|
+
select: (data) => data.toString(),
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
|
|
67
|
+
})
|
|
68
|
+
it('should return the proper type when passed to getQueryData', () => {
|
|
69
|
+
const { queryKey } = queryOptions({
|
|
70
|
+
queryKey: ['key'],
|
|
71
|
+
queryFn: () => Promise.resolve(5),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const queryClient = new QueryClient()
|
|
75
|
+
const data = queryClient.getQueryData(queryKey)
|
|
76
|
+
|
|
77
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
78
|
+
})
|
|
79
|
+
it('should properly type updaterFn when passed to setQueryData', () => {
|
|
80
|
+
const { queryKey } = queryOptions({
|
|
81
|
+
queryKey: ['key'],
|
|
82
|
+
queryFn: () => Promise.resolve(5),
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const queryClient = new QueryClient()
|
|
86
|
+
const data = queryClient.setQueryData(queryKey, (prev) => {
|
|
87
|
+
expectTypeOf(prev).toEqualTypeOf<number | undefined>()
|
|
88
|
+
return prev
|
|
89
|
+
})
|
|
90
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
91
|
+
})
|
|
92
|
+
it('should properly type value when passed to setQueryData', () => {
|
|
93
|
+
const { queryKey } = queryOptions({
|
|
94
|
+
queryKey: ['key'],
|
|
95
|
+
queryFn: () => Promise.resolve(5),
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const queryClient = new QueryClient()
|
|
99
|
+
|
|
100
|
+
// @ts-expect-error value should be a number
|
|
101
|
+
queryClient.setQueryData(queryKey, '5')
|
|
102
|
+
// @ts-expect-error value should be a number
|
|
103
|
+
queryClient.setQueryData(queryKey, () => '5')
|
|
104
|
+
|
|
105
|
+
const data = queryClient.setQueryData(queryKey, 5)
|
|
106
|
+
|
|
107
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
108
|
+
})
|
|
109
|
+
it('should allow to be passed to QueryClient methods while containing ref in queryKey', () => {
|
|
110
|
+
const options = queryOptions({
|
|
111
|
+
queryKey: ['key', ref(1), { nested: ref(2) }],
|
|
112
|
+
queryFn: () => Promise.resolve(5),
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const queryClient = new QueryClient()
|
|
116
|
+
|
|
117
|
+
// Should not error
|
|
118
|
+
const data = queryClient.invalidateQueries(options)
|
|
119
|
+
// Should not error
|
|
120
|
+
const data2 = queryClient.fetchQuery(options)
|
|
121
|
+
|
|
122
|
+
expectTypeOf(data).toEqualTypeOf<Promise<void>>()
|
|
123
|
+
expectTypeOf(data2).toEqualTypeOf<Promise<number>>()
|
|
124
|
+
})
|
|
125
|
+
})
|
|
@@ -50,13 +50,3 @@ export function successMutator<T>(param: T): Promise<T> {
|
|
|
50
50
|
export function errorMutator<T>(_: T): Promise<Error> {
|
|
51
51
|
return rejectFetcher()
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
export type Equal<TTargetA, TTargetB> = (<T>() => T extends TTargetA
|
|
55
|
-
? 1
|
|
56
|
-
: 2) extends <T>() => T extends TTargetB ? 1 : 2
|
|
57
|
-
? true
|
|
58
|
-
: false
|
|
59
|
-
|
|
60
|
-
export type Expect<T extends true> = T
|
|
61
|
-
|
|
62
|
-
export const doNotExecute = (_func: () => void) => true
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { reactive } from 'vue-demi'
|
|
3
|
+
import { useInfiniteQuery } from '../useInfiniteQuery'
|
|
4
|
+
import { simpleFetcher } from './test-utils'
|
|
5
|
+
import type { InfiniteData } from '@tanstack/query-core'
|
|
6
|
+
|
|
7
|
+
describe('Discriminated union return type', () => {
|
|
8
|
+
it('data should be possibly undefined by default', () => {
|
|
9
|
+
const query = reactive(
|
|
10
|
+
useInfiniteQuery({
|
|
11
|
+
queryKey: ['infiniteQuery'],
|
|
12
|
+
queryFn: simpleFetcher,
|
|
13
|
+
getNextPageParam: () => undefined,
|
|
14
|
+
initialPageParam: 0,
|
|
15
|
+
}),
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
// TODO: Order of generics prevents pageParams to be typed correctly. Using `unknown` for now
|
|
19
|
+
expectTypeOf(query.data).toEqualTypeOf<
|
|
20
|
+
InfiniteData<string, unknown> | undefined
|
|
21
|
+
>()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('data should be defined when query is success', () => {
|
|
25
|
+
const query = reactive(
|
|
26
|
+
useInfiniteQuery({
|
|
27
|
+
queryKey: ['infiniteQuery'],
|
|
28
|
+
queryFn: simpleFetcher,
|
|
29
|
+
getNextPageParam: () => undefined,
|
|
30
|
+
initialPageParam: 0,
|
|
31
|
+
}),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if (query.isSuccess) {
|
|
35
|
+
// TODO: Order of generics prevents pageParams to be typed correctly. Using `unknown` for now
|
|
36
|
+
expectTypeOf(query.data).toEqualTypeOf<InfiniteData<string, unknown>>()
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('error should be null when query is success', () => {
|
|
41
|
+
const query = reactive(
|
|
42
|
+
useInfiniteQuery({
|
|
43
|
+
queryKey: ['infiniteQuery'],
|
|
44
|
+
queryFn: simpleFetcher,
|
|
45
|
+
getNextPageParam: () => undefined,
|
|
46
|
+
initialPageParam: 0,
|
|
47
|
+
}),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if (query.isSuccess) {
|
|
51
|
+
expectTypeOf(query.error).toEqualTypeOf<null>()
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('data should be undefined when query is pending', () => {
|
|
56
|
+
const query = reactive(
|
|
57
|
+
useInfiniteQuery({
|
|
58
|
+
queryKey: ['infiniteQuery'],
|
|
59
|
+
queryFn: simpleFetcher,
|
|
60
|
+
getNextPageParam: () => undefined,
|
|
61
|
+
initialPageParam: 0,
|
|
62
|
+
}),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if (query.isPending) {
|
|
66
|
+
expectTypeOf(query.data).toEqualTypeOf<undefined>()
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('error should be defined when query is error', () => {
|
|
71
|
+
const query = reactive(
|
|
72
|
+
useInfiniteQuery({
|
|
73
|
+
queryKey: ['infiniteQuery'],
|
|
74
|
+
queryFn: simpleFetcher,
|
|
75
|
+
getNextPageParam: () => undefined,
|
|
76
|
+
initialPageParam: 0,
|
|
77
|
+
}),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if (query.isError) {
|
|
81
|
+
expectTypeOf(query.error).toEqualTypeOf<Error>()
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test, vi } from 'vitest'
|
|
2
2
|
import { useInfiniteQuery } from '../useInfiniteQuery'
|
|
3
|
+
import { infiniteQueryOptions } from '../infiniteQueryOptions'
|
|
3
4
|
import { flushPromises, infiniteFetcher } from './test-utils'
|
|
4
5
|
|
|
5
6
|
vi.mock('../useQueryClient')
|
|
@@ -28,6 +29,37 @@ describe('useQuery', () => {
|
|
|
28
29
|
|
|
29
30
|
await flushPromises()
|
|
30
31
|
|
|
32
|
+
expect(data.value).toStrictEqual({
|
|
33
|
+
pageParams: [0, 12],
|
|
34
|
+
pages: ['data on page 0', 'data on page 12'],
|
|
35
|
+
})
|
|
36
|
+
expect(status.value).toStrictEqual('success')
|
|
37
|
+
})
|
|
38
|
+
test('should properly execute infinite query using infiniteQueryOptions', async () => {
|
|
39
|
+
const options = infiniteQueryOptions({
|
|
40
|
+
queryKey: ['infiniteQueryOptions'],
|
|
41
|
+
queryFn: infiniteFetcher,
|
|
42
|
+
initialPageParam: 0,
|
|
43
|
+
getNextPageParam: () => 12,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const { data, fetchNextPage, status } = useInfiniteQuery(options)
|
|
47
|
+
|
|
48
|
+
expect(data.value).toStrictEqual(undefined)
|
|
49
|
+
expect(status.value).toStrictEqual('pending')
|
|
50
|
+
|
|
51
|
+
await flushPromises()
|
|
52
|
+
|
|
53
|
+
expect(data.value).toStrictEqual({
|
|
54
|
+
pageParams: [0],
|
|
55
|
+
pages: ['data on page 0'],
|
|
56
|
+
})
|
|
57
|
+
expect(status.value).toStrictEqual('success')
|
|
58
|
+
|
|
59
|
+
fetchNextPage()
|
|
60
|
+
|
|
61
|
+
await flushPromises()
|
|
62
|
+
|
|
31
63
|
expect(data.value).toStrictEqual({
|
|
32
64
|
pageParams: [0, 12],
|
|
33
65
|
pages: ['data on page 0', 'data on page 12'],
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { reactive } from 'vue-demi'
|
|
3
|
+
import { useMutation } from '../useMutation'
|
|
4
|
+
import { successMutator } from './test-utils'
|
|
5
|
+
|
|
6
|
+
describe('Discriminated union return type', () => {
|
|
7
|
+
it('data should be possibly undefined by default', () => {
|
|
8
|
+
const mutation = reactive(
|
|
9
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
expectTypeOf(mutation.data).toEqualTypeOf<string | undefined>()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('data should be defined when mutation is success', () => {
|
|
16
|
+
const mutation = reactive(
|
|
17
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if (mutation.isSuccess) {
|
|
21
|
+
expectTypeOf(mutation.data).toEqualTypeOf<string>()
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('error should be null when mutation is success', () => {
|
|
26
|
+
const mutation = reactive(
|
|
27
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if (mutation.isSuccess) {
|
|
31
|
+
expectTypeOf(mutation.error).toEqualTypeOf<null>()
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('data should be undefined when mutation is pending', () => {
|
|
36
|
+
const mutation = reactive(
|
|
37
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if (mutation.isPending) {
|
|
41
|
+
expectTypeOf(mutation.data).toEqualTypeOf<undefined>()
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('error should be defined when mutation is error', () => {
|
|
46
|
+
const mutation = reactive(
|
|
47
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if (mutation.isError) {
|
|
51
|
+
expectTypeOf(mutation.error).toEqualTypeOf<Error>()
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('should narrow variables', () => {
|
|
56
|
+
const mutation = reactive(
|
|
57
|
+
useMutation({ mutationFn: successMutator<string> }),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
if (mutation.isIdle) {
|
|
61
|
+
expectTypeOf(mutation.variables).toEqualTypeOf<undefined>()
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
if (mutation.isPending) {
|
|
65
|
+
expectTypeOf(mutation.variables).toEqualTypeOf<string>()
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
if (mutation.isSuccess) {
|
|
69
|
+
expectTypeOf(mutation.variables).toEqualTypeOf<string>()
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
expectTypeOf(mutation.variables).toEqualTypeOf<string>()
|
|
73
|
+
})
|
|
74
|
+
})
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { reactive } from 'vue'
|
|
3
|
+
import { skipToken, useQueries } from '..'
|
|
4
|
+
import { queryOptions } from '../queryOptions'
|
|
5
|
+
import type { OmitKeyof, QueryObserverResult } from '..'
|
|
6
|
+
import type { UseQueryOptions } from '../useQuery'
|
|
7
|
+
|
|
8
|
+
describe('UseQueries config object overload', () => {
|
|
9
|
+
it('TData should always be defined when initialData is provided as an object', () => {
|
|
10
|
+
const query1 = {
|
|
11
|
+
queryKey: ['key1'],
|
|
12
|
+
queryFn: () => {
|
|
13
|
+
return {
|
|
14
|
+
wow: true,
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
initialData: {
|
|
18
|
+
wow: false,
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const query2 = queryOptions({
|
|
23
|
+
queryKey: ['key2'],
|
|
24
|
+
queryFn: () => 'Query Data',
|
|
25
|
+
initialData: 'initial data',
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const query3 = {
|
|
29
|
+
queryKey: ['key2'],
|
|
30
|
+
queryFn: () => 'Query Data',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { value: queriesState } = useQueries({
|
|
34
|
+
queries: [query1, query2, query3],
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
expectTypeOf(queriesState[0].data).toEqualTypeOf<{ wow: boolean }>()
|
|
38
|
+
expectTypeOf(queriesState[1].data).toEqualTypeOf<string>()
|
|
39
|
+
expectTypeOf(queriesState[2].data).toEqualTypeOf<string | undefined>()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('TData should be defined when passed through queryOptions', () => {
|
|
43
|
+
const options = queryOptions({
|
|
44
|
+
queryKey: ['key'],
|
|
45
|
+
queryFn: () => {
|
|
46
|
+
return {
|
|
47
|
+
wow: true,
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
initialData: {
|
|
51
|
+
wow: true,
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const { value: queriesState } = useQueries({ queries: [options] })
|
|
56
|
+
|
|
57
|
+
expectTypeOf(queriesState[0].data).toEqualTypeOf<{ wow: boolean }>()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('it should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQueries', () => {
|
|
61
|
+
const query1 = queryOptions({
|
|
62
|
+
queryKey: ['key'],
|
|
63
|
+
queryFn: () => Promise.resolve(1),
|
|
64
|
+
select: (data) => data > 1,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const query2 = {
|
|
68
|
+
queryKey: ['key'],
|
|
69
|
+
queryFn: () => Promise.resolve(1),
|
|
70
|
+
select: (data: any) => data > 1,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const queriesState = reactive(useQueries({ queries: [query1, query2] }))
|
|
74
|
+
|
|
75
|
+
expectTypeOf(queriesState.value[0].data).toEqualTypeOf<
|
|
76
|
+
boolean | undefined
|
|
77
|
+
>()
|
|
78
|
+
expectTypeOf(queriesState.value[1].data).toEqualTypeOf<
|
|
79
|
+
boolean | undefined
|
|
80
|
+
>()
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => {
|
|
84
|
+
const { value: queriesState } = useQueries({
|
|
85
|
+
queries: [
|
|
86
|
+
{
|
|
87
|
+
queryKey: ['key'],
|
|
88
|
+
queryFn: () => {
|
|
89
|
+
return {
|
|
90
|
+
wow: true,
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
initialData: () => undefined as { wow: boolean } | undefined,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
expectTypeOf(queriesState[0].data).toEqualTypeOf<
|
|
99
|
+
{ wow: boolean } | undefined
|
|
100
|
+
>()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('TData should have correct type when conditional skipToken is passed', () => {
|
|
104
|
+
const { value: queriesState } = useQueries({
|
|
105
|
+
queries: [
|
|
106
|
+
queryOptions({
|
|
107
|
+
queryKey: ['key'],
|
|
108
|
+
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
|
|
109
|
+
}),
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const firstResult = queriesState[0]
|
|
114
|
+
|
|
115
|
+
expectTypeOf(firstResult).toEqualTypeOf<
|
|
116
|
+
QueryObserverResult<number, Error>
|
|
117
|
+
>()
|
|
118
|
+
expectTypeOf(firstResult.data).toEqualTypeOf<number | undefined>()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('custom hook', () => {
|
|
122
|
+
it('should allow custom hooks using UseQueryOptions', () => {
|
|
123
|
+
const useCustomQueries = (
|
|
124
|
+
options?: OmitKeyof<
|
|
125
|
+
UseQueryOptions<string>,
|
|
126
|
+
'queryKey' | 'queryFn',
|
|
127
|
+
'safely'
|
|
128
|
+
>,
|
|
129
|
+
) =>
|
|
130
|
+
useQueries({
|
|
131
|
+
queries: [
|
|
132
|
+
{
|
|
133
|
+
...options,
|
|
134
|
+
queryKey: ['todos-key'],
|
|
135
|
+
queryFn: () => Promise.resolve('data'),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const { value: queriesState } = useCustomQueries()
|
|
141
|
+
|
|
142
|
+
expectTypeOf(queriesState[0].data).toEqualTypeOf<string | undefined>()
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
})
|