Skip to content

Commit 0a9f91e

Browse files
committed
feat(query-core): add simplified query methods
1 parent 3894b05 commit 0a9f91e

5 files changed

Lines changed: 1413 additions & 115 deletions

File tree

.changeset/true-cameras-wash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/query-core': minor
3+
---
4+
5+
add query and infiniteQuery methods, deprecate old imperative methods

packages/query-core/src/__tests__/queryClient.test-d.tsx

Lines changed: 171 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { assertType, describe, expectTypeOf, it } from 'vitest'
22
import { queryKey } from '@tanstack/query-test-utils'
33
import { QueryClient } from '../queryClient'
4+
import { skipToken } from '../utils'
45
import type { MutationFilters, QueryFilters, Updater } from '../utils'
56
import type { Mutation } from '../mutation'
67
import type { Query, QueryState } from '../query'
@@ -11,6 +12,7 @@ import type {
1112
EnsureQueryDataOptions,
1213
FetchInfiniteQueryOptions,
1314
InfiniteData,
15+
InfiniteQueryExecuteOptions,
1416
MutationOptions,
1517
OmitKeyof,
1618
QueryKey,
@@ -158,7 +160,38 @@ describe('getQueryState', () => {
158160
})
159161
})
160162

163+
describe('fetchQuery', () => {
164+
it('should not allow passing select option', () => {
165+
assertType<Parameters<QueryClient['fetchQuery']>>([
166+
{
167+
queryKey: ['key'],
168+
queryFn: () => Promise.resolve('string'),
169+
// @ts-expect-error `select` is not supported on fetchQuery options
170+
select: (data: string) => data.length,
171+
},
172+
])
173+
})
174+
})
175+
161176
describe('fetchInfiniteQuery', () => {
177+
it('should not allow passing select option', () => {
178+
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
179+
{
180+
queryKey: ['key'],
181+
queryFn: () => Promise.resolve({ count: 1 }),
182+
initialPageParam: 1,
183+
getNextPageParam: () => 2,
184+
// @ts-expect-error `select` is not supported on fetchInfiniteQuery options
185+
select: (data) => ({
186+
pages: data.pages.map(
187+
(x: unknown) => `count: ${(x as { count: number }).count}`,
188+
),
189+
pageParams: data.pageParams,
190+
}),
191+
},
192+
])
193+
})
194+
162195
it('should allow passing pages', async () => {
163196
const data = await new QueryClient().fetchInfiniteQuery({
164197
queryKey: queryKey(),
@@ -171,7 +204,7 @@ describe('fetchInfiniteQuery', () => {
171204
expectTypeOf(data).toEqualTypeOf<InfiniteData<string, number>>()
172205
})
173206

174-
it('should not allow passing getNextPageParam without pages', () => {
207+
it('should allow passing getNextPageParam without pages', () => {
175208
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
176209
{
177210
queryKey: ['key'],
@@ -195,6 +228,105 @@ describe('fetchInfiniteQuery', () => {
195228
})
196229
})
197230

231+
describe('query', () => {
232+
it('should allow passing select option', () => {
233+
const result = new QueryClient().query({
234+
queryKey: ['key'],
235+
queryFn: () => Promise.resolve('string'),
236+
select: (data) => data.length,
237+
})
238+
239+
expectTypeOf(result).toEqualTypeOf<Promise<number>>()
240+
})
241+
242+
it('should infer select type with skipToken queryFn', () => {
243+
const result = new QueryClient().query({
244+
queryKey: ['key'],
245+
queryFn: skipToken,
246+
select: (data: string) => data.length,
247+
})
248+
249+
expectTypeOf(result).toEqualTypeOf<Promise<number>>()
250+
})
251+
252+
it('should infer select type with skipToken queryFn and enabled false', () => {
253+
const result = new QueryClient().query({
254+
queryKey: ['key'],
255+
queryFn: skipToken,
256+
enabled: false,
257+
select: (data: string) => data.length,
258+
})
259+
260+
expectTypeOf(result).toEqualTypeOf<Promise<number>>()
261+
})
262+
263+
it('should infer select type with skipToken queryFn and enabled true', () => {
264+
const result = new QueryClient().query({
265+
queryKey: ['key'],
266+
queryFn: skipToken,
267+
enabled: true,
268+
select: (data: string) => data.length,
269+
})
270+
271+
expectTypeOf(result).toEqualTypeOf<Promise<number>>()
272+
})
273+
})
274+
275+
describe('infiniteQuery', () => {
276+
it('should allow passing select option', () => {
277+
const result = new QueryClient().infiniteQuery({
278+
queryKey: ['key'],
279+
queryFn: () => Promise.resolve({ count: 1 }),
280+
initialPageParam: 1,
281+
getNextPageParam: () => 2,
282+
select: (data) => ({
283+
pages: data.pages.map(
284+
(x) => `count: ${(x as { count: number }).count}`,
285+
),
286+
}),
287+
})
288+
289+
expectTypeOf(result).toEqualTypeOf<Promise<{ pages: Array<string> }>>()
290+
})
291+
292+
it('should allow passing pages', async () => {
293+
const result = await new QueryClient().infiniteQuery({
294+
queryKey: ['key'],
295+
queryFn: () => Promise.resolve({ count: 1 }),
296+
getNextPageParam: () => 1,
297+
initialPageParam: 1,
298+
pages: 5,
299+
})
300+
301+
expectTypeOf(result).toEqualTypeOf<
302+
InfiniteData<{ count: number }, number>
303+
>()
304+
})
305+
306+
it('should allow passing getNextPageParam without pages', () => {
307+
assertType<Parameters<QueryClient['infiniteQuery']>>([
308+
{
309+
queryKey: ['key'],
310+
queryFn: () => Promise.resolve({ count: 1 }),
311+
initialPageParam: 1,
312+
getNextPageParam: () => 1,
313+
},
314+
])
315+
})
316+
317+
it('should not allow passing pages without getNextPageParam', () => {
318+
assertType<Parameters<QueryClient['infiniteQuery']>>([
319+
// @ts-expect-error Property 'getNextPageParam' is missing
320+
{
321+
queryKey: ['key'],
322+
queryFn: () => Promise.resolve('string'),
323+
initialPageParam: 1,
324+
pages: 5,
325+
},
326+
])
327+
})
328+
})
329+
198330
describe('defaultOptions', () => {
199331
it('should have a typed QueryFunctionContext', () => {
200332
new QueryClient({
@@ -228,19 +360,35 @@ describe('fully typed usage', () => {
228360
// Construct typed arguments
229361
//
230362

363+
const infiniteQueryOptions: InfiniteQueryExecuteOptions<
364+
TData,
365+
TError,
366+
InfiniteData<TData>
367+
> = {
368+
queryKey: ['key', 'infinite'],
369+
pages: 5,
370+
getNextPageParam: (lastPage) => {
371+
expectTypeOf(lastPage).toEqualTypeOf<TData>()
372+
return 0
373+
},
374+
initialPageParam: 0,
375+
}
376+
231377
const queryOptions: EnsureQueryDataOptions<TData, TError> = {
232-
queryKey: ['key'] as any,
378+
queryKey: ['key', 'query'],
233379
}
380+
234381
const fetchInfiniteQueryOptions: FetchInfiniteQueryOptions<TData, TError> =
235382
{
236-
queryKey: ['key'] as any,
383+
queryKey: ['key', 'infinite'],
237384
pages: 5,
238385
getNextPageParam: (lastPage) => {
239386
expectTypeOf(lastPage).toEqualTypeOf<TData>()
240387
return 0
241388
},
242389
initialPageParam: 0,
243390
}
391+
244392
const mutationOptions: MutationOptions<TData, TError> = {}
245393

246394
const queryFilters: QueryFilters<DataTag<QueryKey, TData, TError>> = {
@@ -311,11 +459,19 @@ describe('fully typed usage', () => {
311459
const fetchedQuery = await queryClient.fetchQuery(queryOptions)
312460
expectTypeOf(fetchedQuery).toEqualTypeOf<TData>()
313461

462+
const queriedData = await queryClient.query(queryOptions)
463+
expectTypeOf(queriedData).toEqualTypeOf<TData>()
464+
314465
queryClient.prefetchQuery(queryOptions)
315466

316-
const infiniteQuery = await queryClient.fetchInfiniteQuery(
467+
const fetchInfiniteQueryResult = await queryClient.fetchInfiniteQuery(
317468
fetchInfiniteQueryOptions,
318469
)
470+
expectTypeOf(fetchInfiniteQueryResult).toEqualTypeOf<
471+
InfiniteData<TData, unknown>
472+
>()
473+
474+
const infiniteQuery = await queryClient.infiniteQuery(infiniteQueryOptions)
319475
expectTypeOf(infiniteQuery).toEqualTypeOf<InfiniteData<TData, unknown>>()
320476

321477
const infiniteQueryData = await queryClient.ensureInfiniteQueryData(
@@ -450,9 +606,19 @@ describe('fully typed usage', () => {
450606
const fetchedQuery = await queryClient.fetchQuery(queryOptions)
451607
expectTypeOf(fetchedQuery).toEqualTypeOf<unknown>()
452608

609+
const queriedData = await queryClient.query(queryOptions)
610+
expectTypeOf(queriedData).toEqualTypeOf<unknown>()
611+
453612
queryClient.prefetchQuery(queryOptions)
454613

455-
const infiniteQuery = await queryClient.fetchInfiniteQuery(
614+
const fetchInfiniteQueryResult = await queryClient.fetchInfiniteQuery(
615+
fetchInfiniteQueryOptions,
616+
)
617+
expectTypeOf(fetchInfiniteQueryResult).toEqualTypeOf<
618+
InfiniteData<unknown, unknown>
619+
>()
620+
621+
const infiniteQuery = await queryClient.infiniteQuery(
456622
fetchInfiniteQueryOptions,
457623
)
458624
expectTypeOf(infiniteQuery).toEqualTypeOf<InfiniteData<unknown, unknown>>()

0 commit comments

Comments
 (0)