Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6dd8fbf
init query rename and delegation
DogPawHat Nov 1, 2025
c824b11
update spelling
DogPawHat Nov 1, 2025
4f5f27a
add respect for select
DogPawHat Nov 2, 2025
c7bea26
react query options testing
DogPawHat Nov 2, 2025
269ed8e
update changeset
DogPawHat Nov 2, 2025
f0217b4
ci: apply automated fixes
autofix-ci[bot] Nov 2, 2025
19b13cf
fixes
DogPawHat Nov 2, 2025
311b3ba
more type fixes
DogPawHat Nov 2, 2025
fd8ea67
fix typo
DogPawHat Nov 2, 2025
058fd5c
typo again
DogPawHat Nov 3, 2025
a2c989b
Type fix
DogPawHat Nov 3, 2025
a78d0fe
revert delegations
DogPawHat Nov 5, 2025
de3f12d
typo
DogPawHat Nov 5, 2025
1ed5851
client update async
DogPawHat Nov 5, 2025
5c40184
REVERT IF OPUS FUCKED UP
DogPawHat Nov 27, 2025
bf15113
pages nit
DogPawHat Nov 27, 2025
88d795b
Merge branch 'main' into implement-simplified-imperitive-methods
DogPawHat Dec 27, 2025
a905c54
ci: apply automated fixes
autofix-ci[bot] Dec 27, 2025
f89cc80
use a stub query options function
DogPawHat Dec 27, 2025
fedf7b5
use query and infiniteQuery functions directly for type inference
DogPawHat Dec 28, 2025
a743447
Merge branch 'main' into implement-simplified-imperitive-methods
DogPawHat Dec 28, 2025
c7baef7
lint array fix
DogPawHat Dec 28, 2025
0c6ea77
remove explicit typing
DogPawHat Dec 28, 2025
3b0207d
Merge branch 'main' into implement-simplified-imperitive-methods
DogPawHat Dec 28, 2025
984739c
Merge branch 'main' into implement-simplified-imperitive-methods
DogPawHat Feb 14, 2026
08882ab
throw error if enabled: true/skiptoken and no cached data
DogPawHat Feb 23, 2026
c141fe9
fix title
DogPawHat Feb 23, 2026
8c00297
fix title
DogPawHat Feb 24, 2026
09c7acd
Merge branch 'main' into implement-simplified-imperitive-methods
DogPawHat Feb 24, 2026
3e6d373
correct the changeset
DogPawHat Feb 25, 2026
d9f05cc
add more tests for better coverage
DogPawHat Feb 25, 2026
ce4dcb6
better names in tests
DogPawHat Feb 25, 2026
6c25c3c
more test coverage
DogPawHat Feb 25, 2026
4d70a42
typo
DogPawHat Feb 25, 2026
21be54a
check if error throw in query is redudant
DogPawHat Feb 26, 2026
c44375a
ci: apply automated fixes
autofix-ci[bot] Feb 26, 2026
bbdad0a
remove accidental md commit
DogPawHat Feb 27, 2026
f6f4df2
change error message
DogPawHat Feb 27, 2026
43b553a
update incorrect enabled
DogPawHat Feb 27, 2026
cf7b252
update tests
DogPawHat Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/famous-owls-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@tanstack/react-query': minor
'@tanstack/query-core': minor
'@tanstack/vue-query': minor
---

add query() and infiniteQuery() imperative methods to QueryClient
182 changes: 174 additions & 8 deletions packages/query-core/src/__tests__/queryClient.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { QueryClient } from '../queryClient'
import { skipToken } from '../utils'
import type { MutationFilters, QueryFilters, Updater } from '../utils'
import type { Mutation } from '../mutation'
import type { Query, QueryState } from '../query'
Expand All @@ -10,6 +11,7 @@ import type {
EnsureQueryDataOptions,
FetchInfiniteQueryOptions,
InfiniteData,
InfiniteQueryExecuteOptions,
MutationOptions,
OmitKeyof,
QueryKey,
Expand Down Expand Up @@ -157,24 +159,55 @@ describe('getQueryState', () => {
})
})

describe('fetchQuery', () => {
it('should not allow passing select option', () => {
assertType<Parameters<QueryClient['fetchQuery']>>([
{
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
// @ts-expect-error `select` is not supported on fetchQuery options
select: (data: string) => data.length,
},
])
})
})

describe('fetchInfiniteQuery', () => {
it('should not allow passing select option', () => {
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
{
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
initialPageParam: 1,
getNextPageParam: () => 2,
// @ts-expect-error `select` is not supported on fetchInfiniteQuery options
select: (data) => ({
pages: data.pages.map(
(x: unknown) => `count: ${(x as { count: number }).count}`,
),
pageParams: data.pageParams,
}),
},
])
})

it('should allow passing pages', async () => {
const data = await new QueryClient().fetchInfiniteQuery({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
queryFn: () => Promise.resolve({ count: 1 }),
getNextPageParam: () => 1,
initialPageParam: 1,
pages: 5,
})

expectTypeOf(data).toEqualTypeOf<InfiniteData<string, number>>()
expectTypeOf(data).toEqualTypeOf<InfiniteData<{ count: number }, number>>()
})

it('should not allow passing getNextPageParam without pages', () => {
it('should allow passing getNextPageParam without pages', () => {
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
{
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
queryFn: () => Promise.resolve({ count: 1 }),
initialPageParam: 1,
getNextPageParam: () => 1,
},
Expand All @@ -183,6 +216,105 @@ describe('fetchInfiniteQuery', () => {

it('should not allow passing pages without getNextPageParam', () => {
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
// @ts-expect-error Property 'getNextPageParam' is missing
{
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
initialPageParam: 1,
pages: 5,
},
])
})
})

describe('query', () => {
it('should allow passing select option', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
select: (data) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken queryFn', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken queryFn and enabled false', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
enabled: false,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken queryFn and enabled true', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
enabled: true,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})
})

describe('infiniteQuery', () => {
it('should allow passing select option', () => {
const result = new QueryClient().infiniteQuery({
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
initialPageParam: 1,
getNextPageParam: () => 2,
select: (data) => ({
pages: data.pages.map(
(x) => `count: ${(x as { count: number }).count}`,
),
}),
})

expectTypeOf(result).toEqualTypeOf<Promise<{ pages: Array<string> }>>()
})

it('should allow passing pages', async () => {
const result = await new QueryClient().infiniteQuery({
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
getNextPageParam: () => 1,
initialPageParam: 1,
pages: 5,
})

expectTypeOf(result).toEqualTypeOf<
InfiniteData<{ count: number }, number>
>()
})

it('should allow passing getNextPageParam without pages', () => {
assertType<Parameters<QueryClient['infiniteQuery']>>([
{
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
initialPageParam: 1,
getNextPageParam: () => 1,
},
])
})

it('should not allow passing pages without getNextPageParam', () => {
assertType<Parameters<QueryClient['infiniteQuery']>>([
// @ts-expect-error Property 'getNextPageParam' is missing
{
queryKey: ['key'],
Expand Down Expand Up @@ -227,19 +359,35 @@ describe('fully typed usage', () => {
// Construct typed arguments
//

const infiniteQueryOptions: InfiniteQueryExecuteOptions<
TData,
TError,
InfiniteData<TData>
> = {
queryKey: ['key', 'infinite'],
pages: 5,
getNextPageParam: (lastPage) => {
expectTypeOf(lastPage).toEqualTypeOf<TData>()
return 0
},
initialPageParam: 0,
}

const queryOptions: EnsureQueryDataOptions<TData, TError> = {
queryKey: ['key'] as any,
queryKey: ['key', 'query'],
}

const fetchInfiniteQueryOptions: FetchInfiniteQueryOptions<TData, TError> =
{
queryKey: ['key'] as any,
queryKey: ['key', 'infinite'],
pages: 5,
getNextPageParam: (lastPage) => {
expectTypeOf(lastPage).toEqualTypeOf<TData>()
return 0
},
initialPageParam: 0,
}

const mutationOptions: MutationOptions<TData, TError> = {}

const queryFilters: QueryFilters<DataTag<QueryKey, TData, TError>> = {
Expand Down Expand Up @@ -310,11 +458,19 @@ describe('fully typed usage', () => {
const fetchedQuery = await queryClient.fetchQuery(queryOptions)
expectTypeOf(fetchedQuery).toEqualTypeOf<TData>()

const queriedData = await queryClient.query(queryOptions)
expectTypeOf(queriedData).toEqualTypeOf<TData>()

queryClient.prefetchQuery(queryOptions)

const infiniteQuery = await queryClient.fetchInfiniteQuery(
const fetchInfiniteQueryResult = await queryClient.fetchInfiniteQuery(
fetchInfiniteQueryOptions,
)
expectTypeOf(fetchInfiniteQueryResult).toEqualTypeOf<
InfiniteData<TData, unknown>
>()

const infiniteQuery = await queryClient.infiniteQuery(infiniteQueryOptions)
expectTypeOf(infiniteQuery).toEqualTypeOf<InfiniteData<TData, unknown>>()

const infiniteQueryData = await queryClient.ensureInfiniteQueryData(
Expand Down Expand Up @@ -449,9 +605,19 @@ describe('fully typed usage', () => {
const fetchedQuery = await queryClient.fetchQuery(queryOptions)
expectTypeOf(fetchedQuery).toEqualTypeOf<unknown>()

const queriedData = await queryClient.query(queryOptions)
expectTypeOf(queriedData).toEqualTypeOf<unknown>()

queryClient.prefetchQuery(queryOptions)

const infiniteQuery = await queryClient.fetchInfiniteQuery(
const fetchInfiniteQueryResult = await queryClient.fetchInfiniteQuery(
fetchInfiniteQueryOptions,
)
expectTypeOf(fetchInfiniteQueryResult).toEqualTypeOf<
InfiniteData<unknown, unknown>
>()

const infiniteQuery = await queryClient.infiniteQuery(
fetchInfiniteQueryOptions,
)
expectTypeOf(infiniteQuery).toEqualTypeOf<InfiniteData<unknown, unknown>>()
Expand Down
Loading
Loading