From d29124e1a63e4e306abdd5b7ad2819e707b10990 Mon Sep 17 00:00:00 2001 From: Ousama Ben Younes Date: Tue, 21 Jul 2026 13:38:37 +0000 Subject: [PATCH 1/3] fix(vue-query): export queryOptions declaration types --- .changeset/calm-vue-query-options.md | 6 +++ packages/query-core/src/index.ts | 2 + .../src/__tests__/queryOptions.test-d.ts | 39 ++++++++++++++++++ packages/vue-query/src/index.ts | 11 +++-- packages/vue-query/src/queryOptions.ts | 40 ++++++++++++------- 5 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 .changeset/calm-vue-query-options.md diff --git a/.changeset/calm-vue-query-options.md b/.changeset/calm-vue-query-options.md new file mode 100644 index 00000000000..5fecc0b1f97 --- /dev/null +++ b/.changeset/calm-vue-query-options.md @@ -0,0 +1,6 @@ +--- +'@tanstack/query-core': patch +'@tanstack/vue-query': patch +--- + +Export query option declaration helper types for portable Vue queryOptions factories. diff --git a/packages/query-core/src/index.ts b/packages/query-core/src/index.ts index a4267aabc97..07b8916a3e8 100644 --- a/packages/query-core/src/index.ts +++ b/packages/query-core/src/index.ts @@ -20,6 +20,8 @@ export type { QueryCacheNotifyEvent } from './queryCache' export { QueryClient } from './queryClient' export { QueryObserver } from './queryObserver' export { CancelledError, isCancelledError } from './retryer' +export type { RetryDelayValue, RetryValue } from './retryer' +export type { QueryBehavior } from './query' export { timeoutManager, type ManagedTimerId, diff --git a/packages/vue-query/src/__tests__/queryOptions.test-d.ts b/packages/vue-query/src/__tests__/queryOptions.test-d.ts index a3e8c6d0d41..b906ba597cc 100644 --- a/packages/vue-query/src/__tests__/queryOptions.test-d.ts +++ b/packages/vue-query/src/__tests__/queryOptions.test-d.ts @@ -5,6 +5,7 @@ import { queryKey } from '@tanstack/query-test-utils' import { QueryClient } from '../queryClient' import { queryOptions } from '../queryOptions' import { useQuery } from '../useQuery' +import type { QueryOptionsDataTag, UndefinedInitialQueryOptions } from '..' describe('queryOptions', () => { it('should not allow excess properties', () => { @@ -332,4 +333,42 @@ describe('queryOptions', () => { expectTypeOf(options.queryKey).not.toBeUndefined() }) + + it('should allow public queryOptions types to be used in declaration emit', () => { + type Todo = { + id: number + name: string + } + + type TodoOptions = UndefinedInitialQueryOptions< + Todo, + Error, + Todo, + readonly ['todo'] + > + + function todoOptions(): TodoOptions { + return queryOptions({ + queryKey: ['todo'] as const, + queryFn: () => Promise.resolve({ id: 1, name: 'one' }), + }) + } + + expectTypeOf( + queryOptions({ + queryKey: ['todo'] as const, + queryFn: (): Promise => Promise.resolve({ id: 1, name: 'one' }), + }), + ).toEqualTypeOf< + QueryOptionsDataTag + >() + + queryOptions({ + ...todoOptions(), + select: (data) => { + expectTypeOf(data).toEqualTypeOf() + return data.name + }, + }) + }) }) diff --git a/packages/vue-query/src/index.ts b/packages/vue-query/src/index.ts index 36c616b12af..d39917ad2b6 100644 --- a/packages/vue-query/src/index.ts +++ b/packages/vue-query/src/index.ts @@ -6,7 +6,12 @@ export { VueQueryPlugin } from './vueQueryPlugin' export { QueryClient } from './queryClient' export { QueryCache } from './queryCache' export { queryOptions } from './queryOptions' -export { type QueryOptions } from './queryOptions' +export type { + DefinedInitialQueryOptions, + QueryOptions, + QueryOptionsDataTag, + UndefinedInitialQueryOptions, +} from './queryOptions' export { infiniteQueryOptions } from './infiniteQueryOptions' export type { DefinedInitialDataInfiniteOptions, @@ -30,15 +35,13 @@ export type { UseQueryOptions, UseQueryReturnType, UseQueryDefinedReturnType, - UndefinedInitialQueryOptions, - DefinedInitialQueryOptions, } from './useQuery' export type { UseInfiniteQueryOptions, UseInfiniteQueryReturnType, } from './useInfiniteQuery' export type { UseMutationOptions, UseMutationReturnType } from './useMutation' -export type { MutationOptions } from './types' +export type { MaybeRefOrGetter, MutationOptions, ShallowOption } from './types' export type { UseQueriesOptions, UseQueriesResults } from './useQueries' export type { MutationFilters, MutationStateOptions } from './useMutationState' export type { QueryFilters } from './useIsFetching' diff --git a/packages/vue-query/src/queryOptions.ts b/packages/vue-query/src/queryOptions.ts index 37e7f22b4f5..086e94fea43 100644 --- a/packages/vue-query/src/queryOptions.ts +++ b/packages/vue-query/src/queryOptions.ts @@ -65,6 +65,11 @@ export type DefinedInitialQueryOptions< | (() => NonUndefinedGuard) } +export type QueryOptionsDataTag = + Omit & { + queryKey: DataTag + } + export function queryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -72,9 +77,12 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: DefinedInitialQueryOptions, -): DefinedInitialQueryOptions & { - queryKey: DataTag -} +): QueryOptionsDataTag< + DefinedInitialQueryOptions, + TQueryFnData, + TError, + TQueryKey +> export function queryOptions< TQueryFnData = unknown, @@ -88,9 +96,12 @@ export function queryOptions< TData, TQueryKey >, -): () => DefinedInitialQueryOptions & { - queryKey: DataTag -} +): () => QueryOptionsDataTag< + DefinedInitialQueryOptions, + TQueryFnData, + TError, + TQueryKey +> export function queryOptions< TQueryFnData = unknown, @@ -99,9 +110,12 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: UndefinedInitialQueryOptions, -): UndefinedInitialQueryOptions & { - queryKey: DataTag -} +): QueryOptionsDataTag< + UndefinedInitialQueryOptions, + TQueryFnData, + TError, + TQueryKey +> export function queryOptions< TQueryFnData = unknown, @@ -115,14 +129,12 @@ export function queryOptions< TData, TQueryKey >, -): () => UndefinedInitialQueryOptions< +): () => QueryOptionsDataTag< + UndefinedInitialQueryOptions, TQueryFnData, TError, - TData, TQueryKey -> & { - queryKey: DataTag -} +> export function queryOptions(options: unknown) { return options From c49e527861ac4558a9df709efd4d836c6693c068 Mon Sep 17 00:00:00 2001 From: Ousama Ben Younes Date: Tue, 21 Jul 2026 16:04:03 +0000 Subject: [PATCH 2/3] fix(vue-query): expose useQuery option aliases --- .changeset/calm-vue-query-options.md | 2 ++ packages/vue-query/src/index.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.changeset/calm-vue-query-options.md b/.changeset/calm-vue-query-options.md index 5fecc0b1f97..331c4338c6b 100644 --- a/.changeset/calm-vue-query-options.md +++ b/.changeset/calm-vue-query-options.md @@ -4,3 +4,5 @@ --- Export query option declaration helper types for portable Vue queryOptions factories. +The previous `useQuery`-specific initial-data helper types remain available as +`UndefinedInitialUseQueryOptions` and `DefinedInitialUseQueryOptions`. diff --git a/packages/vue-query/src/index.ts b/packages/vue-query/src/index.ts index d39917ad2b6..339afc49f9d 100644 --- a/packages/vue-query/src/index.ts +++ b/packages/vue-query/src/index.ts @@ -35,6 +35,8 @@ export type { UseQueryOptions, UseQueryReturnType, UseQueryDefinedReturnType, + UndefinedInitialQueryOptions as UndefinedInitialUseQueryOptions, + DefinedInitialQueryOptions as DefinedInitialUseQueryOptions, } from './useQuery' export type { UseInfiniteQueryOptions, From 722169cf5dc6adae3481c0630ad054736e765123 Mon Sep 17 00:00:00 2001 From: Ousama Ben Younes Date: Tue, 21 Jul 2026 16:06:49 +0000 Subject: [PATCH 3/3] fix(vue-query): preserve reactive query option keys --- .../src/__tests__/queryOptions.test-d.ts | 16 ++++- packages/vue-query/src/queryOptions.ts | 59 +++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/packages/vue-query/src/__tests__/queryOptions.test-d.ts b/packages/vue-query/src/__tests__/queryOptions.test-d.ts index b906ba597cc..64c4f32f383 100644 --- a/packages/vue-query/src/__tests__/queryOptions.test-d.ts +++ b/packages/vue-query/src/__tests__/queryOptions.test-d.ts @@ -5,6 +5,8 @@ import { queryKey } from '@tanstack/query-test-utils' import { QueryClient } from '../queryClient' import { queryOptions } from '../queryOptions' import { useQuery } from '../useQuery' +import type { ComputedRef, Ref } from 'vue-demi' +import type { DataTag } from '@tanstack/query-core' import type { QueryOptionsDataTag, UndefinedInitialQueryOptions } from '..' describe('queryOptions', () => { @@ -309,7 +311,11 @@ describe('queryOptions', () => { queryFn: () => Promise.resolve({ id: '1' }), }) - expectTypeOf(options.queryKey).not.toBeUndefined() + expectTypeOf(options.queryKey).toEqualTypeOf< + ComputedRef< + DataTag + > + >() }) it('should allow ref as queryKey', () => { @@ -320,7 +326,9 @@ describe('queryOptions', () => { queryFn: () => Promise.resolve({ id: '1' }), }) - expectTypeOf(options.queryKey).not.toBeUndefined() + expectTypeOf(options.queryKey).toEqualTypeOf< + Ref> + >() }) it('should allow getter function as queryKey', () => { @@ -331,7 +339,9 @@ describe('queryOptions', () => { queryFn: () => Promise.resolve({ id: '1' }), }) - expectTypeOf(options.queryKey).not.toBeUndefined() + expectTypeOf(options.queryKey).toEqualTypeOf< + () => DataTag + >() }) it('should allow public queryOptions types to be used in declaration emit', () => { diff --git a/packages/vue-query/src/queryOptions.ts b/packages/vue-query/src/queryOptions.ts index 086e94fea43..44c53d66574 100644 --- a/packages/vue-query/src/queryOptions.ts +++ b/packages/vue-query/src/queryOptions.ts @@ -1,4 +1,5 @@ import type { DeepUnwrapRef, MaybeRefOrGetter, ShallowOption } from './types' +import type { ComputedRef, Ref } from 'vue-demi' import type { DataTag, DefaultError, @@ -67,18 +68,42 @@ export type DefinedInitialQueryOptions< export type QueryOptionsDataTag = Omit & { - queryKey: DataTag + queryKey: TaggedQueryKey< + TOptions, + TQueryFnData, + TError, + TQueryKey + > } +type TaggedQueryKey = + TOptions extends { queryKey: infer TQueryKeyOption } + ? TQueryKeyOption extends () => infer TQueryKeyFromGetter + ? () => DataTag + : TQueryKeyOption extends ComputedRef + ? ComputedRef> + : TQueryKeyOption extends Ref + ? Ref> + : TQueryKeyOption extends QueryKey + ? DataTag + : DataTag + : DataTag + export function queryOptions< TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, + TOptions extends DefinedInitialQueryOptions< + TQueryFnData, + TError, + TData, + TQueryKey + > = DefinedInitialQueryOptions, >( - options: DefinedInitialQueryOptions, + options: TOptions, ): QueryOptionsDataTag< - DefinedInitialQueryOptions, + TOptions, TQueryFnData, TError, TQueryKey @@ -89,15 +114,16 @@ export function queryOptions< TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, ->( - options: () => DefinedInitialQueryOptions< + TOptions extends DefinedInitialQueryOptions< TQueryFnData, TError, TData, TQueryKey - >, + > = DefinedInitialQueryOptions, +>( + options: () => TOptions, ): () => QueryOptionsDataTag< - DefinedInitialQueryOptions, + TOptions, TQueryFnData, TError, TQueryKey @@ -108,10 +134,16 @@ export function queryOptions< TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, + TOptions extends UndefinedInitialQueryOptions< + TQueryFnData, + TError, + TData, + TQueryKey + > = UndefinedInitialQueryOptions, >( - options: UndefinedInitialQueryOptions, + options: TOptions, ): QueryOptionsDataTag< - UndefinedInitialQueryOptions, + TOptions, TQueryFnData, TError, TQueryKey @@ -122,15 +154,16 @@ export function queryOptions< TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, ->( - options: () => UndefinedInitialQueryOptions< + TOptions extends UndefinedInitialQueryOptions< TQueryFnData, TError, TData, TQueryKey - >, + > = UndefinedInitialQueryOptions, +>( + options: () => TOptions, ): () => QueryOptionsDataTag< - UndefinedInitialQueryOptions, + TOptions, TQueryFnData, TError, TQueryKey