From eac654d006f69cb2e54d2859efcabb0f6beff755 Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Wed, 5 Aug 2026 20:10:10 -0300 Subject: [PATCH] feat(query-core): pass a context object to the placeholderData function placeholderData functions now receive a third argument holding the client, the queryKey and the meta of the Query, matching the QueryFunctionContext that queryFn already gets. Implements the proposal from #11140. --- .changeset/placeholder-data-context.md | 10 + .../angular/guides/placeholder-query-data.md | 19 ++ .../react/guides/placeholder-query-data.md | 23 ++ docs/framework/react/reference/useQueries.md | 2 +- docs/framework/react/reference/useQuery.md | 6 +- docs/framework/solid/reference/useQuery.md | 6 +- .../src/inject-queries.ts | 4 +- packages/preact-query/src/useQueries.ts | 4 +- .../src/__tests__/queryObserver.test-d.tsx | 53 ++++- .../src/__tests__/queryObserver.test.tsx | 207 +++++++++++++++++- packages/query-core/src/queryObserver.ts | 14 +- packages/query-core/src/types.ts | 13 +- .../src/__tests__/useQueries.test-d.tsx | 29 ++- .../src/__tests__/useQuery.test.tsx | 52 ++++- packages/react-query/src/useQueries.ts | 4 +- packages/solid-query/src/useQueries.ts | 4 +- .../svelte-query/src/createQueries.svelte.ts | 4 +- 17 files changed, 433 insertions(+), 21 deletions(-) create mode 100644 .changeset/placeholder-data-context.md diff --git a/.changeset/placeholder-data-context.md b/.changeset/placeholder-data-context.md new file mode 100644 index 00000000000..b3ba5d4cfc7 --- /dev/null +++ b/.changeset/placeholder-data-context.md @@ -0,0 +1,10 @@ +--- +'@tanstack/angular-query-experimental': minor +'@tanstack/preact-query': minor +'@tanstack/query-core': minor +'@tanstack/react-query': minor +'@tanstack/solid-query': minor +'@tanstack/svelte-query': minor +--- + +`placeholderData` functions now receive a third argument holding the `client`, the `queryKey` and the `meta` of the Query, so a `queryOptions` factory can seed from the cache without being given a `QueryClient`. diff --git a/docs/framework/angular/guides/placeholder-query-data.md b/docs/framework/angular/guides/placeholder-query-data.md index ba92fbc4edf..05deb7a4eb9 100644 --- a/docs/framework/angular/guides/placeholder-query-data.md +++ b/docs/framework/angular/guides/placeholder-query-data.md @@ -54,5 +54,24 @@ export class BlogPostComponent { ``` [//]: # 'ExampleCache' +[//]: # 'ExampleCacheContext' + +```ts +@Injectable({ + providedIn: 'root', +}) +export class BlogPostsService { + blogPost(blogPostId: number) { + return queryOptions({ + queryKey: ['blogPost', blogPostId], + queryFn: () => fetch(`/blogPosts/${blogPostId}`), + placeholderData: (_previousData, _previousQuery, { client }) => + client.getQueryData(['blogPosts'])?.find((d) => d.id === blogPostId), + }) + } +} +``` + +[//]: # 'ExampleCacheContext' [//]: # 'Materials' [//]: # 'Materials' diff --git a/docs/framework/react/guides/placeholder-query-data.md b/docs/framework/react/guides/placeholder-query-data.md index c8e5c8ccef7..dc2516c9ae9 100644 --- a/docs/framework/react/guides/placeholder-query-data.md +++ b/docs/framework/react/guides/placeholder-query-data.md @@ -92,6 +92,29 @@ function BlogPost({ blogPostId }) { ``` [//]: # 'ExampleCache' + +### Placeholder Data in a Query Options Factory + +The example above needs the `queryClient` to be available where the options are defined, which is not the case when you extract them into a [`queryOptions`](./query-options.md) factory. To cover that, the `placeholderData` function receives a third argument holding the `client`, the `queryKey` and the `meta` of the Query: + +[//]: # 'ExampleCacheContext' + +```tsx +export const blogPostOptions = (blogPostId: string) => + queryOptions({ + queryKey: ['blogPost', blogPostId], + queryFn: () => fetch(`/blogPosts/${blogPostId}`), + placeholderData: (_previousData, _previousQuery, { client }) => + client.getQueryData(['blogPosts'])?.find((d) => d.id === blogPostId), + }) +``` + +[//]: # 'ExampleCacheContext' + +Note that the property is named `client`, not `queryClient`, to match the [`QueryFunctionContext`](./query-functions.md#queryfunctioncontext) given to the `queryFn`. + +> `placeholderData` runs during render, so only read from the `client` here - do not write to the cache with `setQueryData` or trigger fetches with `invalidateQueries`. + [//]: # 'Materials' ## Further reading diff --git a/docs/framework/react/reference/useQueries.md b/docs/framework/react/reference/useQueries.md index 1048b532d29..daa44c1c932 100644 --- a/docs/framework/react/reference/useQueries.md +++ b/docs/framework/react/reference/useQueries.md @@ -29,7 +29,7 @@ The `useQueries` hook accepts an options object with a **queries** key whose val **placeholderData** -The `placeholderData` option exists for `useQueries` as well, but it doesn't get information passed from previously rendered Queries like `useQuery` does, because the input to `useQueries` can be a different number of Queries on each render. +The `placeholderData` option exists for `useQueries` as well, but it doesn't get information passed from previously rendered Queries like `useQuery` does, because the input to `useQueries` can be a different number of Queries on each render. It does still receive the `PlaceholderDataContext` as its third argument, so the `client`, the `queryKey` and the `meta` of each Query are available. **Returns** diff --git a/docs/framework/react/reference/useQuery.md b/docs/framework/react/reference/useQuery.md index 569e19cb8f4..dd208ca725e 100644 --- a/docs/framework/react/reference/useQuery.md +++ b/docs/framework/react/reference/useQuery.md @@ -157,11 +157,11 @@ const { - `initialDataUpdatedAt: number | (() => number | undefined)` - Optional - If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated. -- `placeholderData: TData | (previousValue: TData | undefined, previousQuery: Query | undefined) => TData` +- `placeholderData: TData | (previousValue: TData | undefined, previousQuery: Query | undefined, context: PlaceholderDataContext) => TData` - Optional - If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state. - `placeholderData` is **not persisted** to the cache - - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance. + - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, the second argument will be the complete previousQuery instance, and the third argument will be a `PlaceholderDataContext` with the `client`, the `queryKey` and the `meta` of this query. - `structuralSharing: boolean | (oldData: unknown | undefined, newData: unknown) => unknown` - Optional - Defaults to `true` @@ -177,7 +177,7 @@ const { - If set to a function, it will be passed the error and the query, and it should return a boolean indicating whether to show the error in an error boundary (`true`) or return the error as state (`false`) - `meta: Record` - Optional - - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`. + - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn` and of the `PlaceholderDataContext` provided to a `placeholderData` function. **Parameter2 (QueryClient)** diff --git a/docs/framework/solid/reference/useQuery.md b/docs/framework/solid/reference/useQuery.md index aaca4469971..d508d6ca268 100644 --- a/docs/framework/solid/reference/useQuery.md +++ b/docs/framework/solid/reference/useQuery.md @@ -205,11 +205,11 @@ function App() { - Optional - This option can be used to transform or select a part of the data returned by the query function. It affects the returned `data` value, but does not affect what gets stored in the query cache. - The `select` function will only run if `data` changed, or if the reference to the `select` function itself changes. To optimize, wrap the function in `useCallback`. - - ##### `placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData` + - ##### `placeholderData: TData | (previousValue: TData | undefined, previousQuery: Query | undefined, context: PlaceholderDataContext) => TData` - Optional - If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state. - `placeholderData` is **not persisted** to the cache - - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance. + - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, the second argument will be the complete previousQuery instance, and the third argument will be a `PlaceholderDataContext` with the `client`, the `queryKey` and the `meta` of this query. - ##### `deferStream: boolean` - Optional - Defaults to `false` @@ -241,7 +241,7 @@ function App() { - If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated. - ##### `meta: Record` - Optional - - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`. + - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn` and of the `PlaceholderDataContext` provided to a `placeholderData` function. - ##### `queryKeyHashFn: (queryKey: QueryKey) => string` - Optional - If specified, this function is used to hash the `queryKey` to a string. diff --git a/packages/angular-query-experimental/src/inject-queries.ts b/packages/angular-query-experimental/src/inject-queries.ts index d61a937a3c2..a7a36c511c3 100644 --- a/packages/angular-query-experimental/src/inject-queries.ts +++ b/packages/angular-query-experimental/src/inject-queries.ts @@ -45,7 +45,9 @@ type QueryObserverOptionsForCreateQueries< CreateQueryOptions, 'placeholderData' > & { - placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction + placeholderData?: + | TQueryFnData + | QueriesPlaceholderDataFunction } // Avoid TS depth-limit error in case of large array literal diff --git a/packages/preact-query/src/useQueries.ts b/packages/preact-query/src/useQueries.ts index 7e30658b843..b3fb601ea45 100644 --- a/packages/preact-query/src/useQueries.ts +++ b/packages/preact-query/src/useQueries.ts @@ -48,7 +48,9 @@ type UseQueryOptionsForUseQueries< UseQueryOptions, 'placeholderData' | 'subscribed' > & { - placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction + placeholderData?: + | TQueryFnData + | QueriesPlaceholderDataFunction } // Avoid TS depth-limit error in case of large array literal diff --git a/packages/query-core/src/__tests__/queryObserver.test-d.tsx b/packages/query-core/src/__tests__/queryObserver.test-d.tsx index 5d929e40ad8..6de0a4d08be 100644 --- a/packages/query-core/src/__tests__/queryObserver.test-d.tsx +++ b/packages/query-core/src/__tests__/queryObserver.test-d.tsx @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expectTypeOf, it } from 'vitest' import { queryKey } from '@tanstack/query-test-utils' -import { QueryClient, QueryObserver } from '..' -import type { DefaultError } from '..' +import { QueryClient, QueryObserver, keepPreviousData } from '..' +import type { DefaultError, QueryMeta } from '..' describe('queryObserver', () => { let queryClient: QueryClient @@ -149,5 +149,54 @@ describe('queryObserver', () => { }, }) }) + + it('context should have a typed queryKey', () => { + const testQueryKey = ['SomeQuery', 42, { foo: 'bar' }] as const + + new QueryObserver(new QueryClient(), { + queryKey: testQueryKey, + placeholderData: (_previousData, _previousQuery, context) => { + expectTypeOf(context.queryKey).toEqualTypeOf() + return undefined + }, + }) + }) + + it('context should have a typed client', () => { + new QueryObserver(new QueryClient(), { + queryKey: queryKey(), + placeholderData: (_previousData, _previousQuery, context) => { + expectTypeOf(context.client).toEqualTypeOf() + return undefined + }, + }) + }) + + it('context should have a typed meta', () => { + new QueryObserver(new QueryClient(), { + queryKey: queryKey(), + placeholderData: (_previousData, _previousQuery, context) => { + expectTypeOf(context.meta).toEqualTypeOf() + return undefined + }, + }) + }) + + it('should accept a function that omits the context parameter', () => { + new QueryObserver(new QueryClient(), { + queryKey: queryKey(), + queryFn: () => 'data', + placeholderData: (previousData) => { + expectTypeOf(previousData).toEqualTypeOf() + return previousData + }, + }) + + new QueryObserver(new QueryClient(), { + queryKey: queryKey(), + queryFn: () => 'data', + placeholderData: keepPreviousData, + }) + }) }) }) diff --git a/packages/query-core/src/__tests__/queryObserver.test.tsx b/packages/query-core/src/__tests__/queryObserver.test.tsx index 557ef79614d..112e2eb4e0c 100644 --- a/packages/query-core/src/__tests__/queryObserver.test.tsx +++ b/packages/query-core/src/__tests__/queryObserver.test.tsx @@ -8,8 +8,8 @@ import { vi, } from 'vitest' import { queryKey, sleep } from '@tanstack/query-test-utils' -import { QueryClient, QueryObserver, focusManager } from '..' -import type { QueryObserverResult } from '..' +import { QueryClient, QueryObserver, focusManager, keepPreviousData } from '..' +import type { PlaceholderDataContext, QueryObserverResult } from '..' describe('queryObserver', () => { let queryClient: QueryClient @@ -1228,6 +1228,209 @@ describe('queryObserver', () => { expect(stableSelect.mock.calls[1]![0]).toEqual(data2) }) + it('should pass a context with the client, queryKey and meta to the placeholderData function', () => { + const key = queryKey() + const meta = { it: 'works' } + const contexts: Array = [] + + const observer = new QueryObserver(queryClient, { + queryKey: key, + queryFn: () => 'data', + meta, + placeholderData: (_previousData, _previousQuery, context) => { + contexts.push(context) + return 'placeholder' + }, + }) + + expect(observer.getCurrentResult()).toMatchObject({ + status: 'success', + data: 'placeholder', + }) + + const context = contexts[0]! + expect(context.client).toBe(queryClient) + expect(context.queryKey).toEqual(key) + expect(context.meta).toBe(meta) + }) + + it('should pass a context with an undefined meta to the placeholderData function when no meta is set', () => { + const key = queryKey() + const contexts: Array = [] + + new QueryObserver(queryClient, { + queryKey: key, + queryFn: () => 'data', + placeholderData: (_previousData, _previousQuery, context) => { + contexts.push(context) + return 'placeholder' + }, + }) + + const context = contexts[0]! + expect('meta' in context).toBe(true) + expect(context.meta).toBeUndefined() + }) + + it('should pass a context with the current queryKey and meta to the placeholderData function after the options change', async () => { + const key1 = queryKey() + const key2 = queryKey() + + const meta1 = { query: 'one' } + const meta2 = { query: 'two' } + + const contexts: Array = [] + const previousKeys: Array | null> = [] + + const observer = new QueryObserver(queryClient, { + queryKey: key1, + queryFn: () => 'data1', + meta: meta1, + placeholderData: (prev) => prev, + }) + + const unsubscribe = observer.subscribe(() => undefined) + + await vi.advanceTimersByTimeAsync(0) + + observer.setOptions({ + queryKey: key2, + queryFn: () => 'data2', + meta: meta2, + placeholderData: (prev, prevQuery, context) => { + contexts.push(context) + previousKeys.push(prevQuery?.queryKey || null) + return prev + }, + }) + + await vi.advanceTimersByTimeAsync(0) + unsubscribe() + + const context = contexts[0]! + expect(context.queryKey).toEqual(key2) + expect(context.meta).toBe(meta2) + expect(previousKeys[0]).toBe(key1) + }) + + it('should pass each observer its own meta to the placeholderData function', () => { + const key = queryKey() + + const meta1 = { observer: 'one' } + const meta2 = { observer: 'two' } + + const contexts: Array = [] + + const observer1 = new QueryObserver(queryClient, { + queryKey: key, + queryFn: () => 'data', + meta: meta1, + placeholderData: 'placeholder1', + }) + + new QueryObserver(queryClient, { + queryKey: key, + queryFn: () => 'data', + meta: meta2, + placeholderData: 'placeholder2', + }) + + observer1.getOptimisticResult( + queryClient.defaultQueryOptions({ + queryKey: key, + queryFn: () => 'data', + meta: meta1, + placeholderData: (_previousData, _previousQuery, context) => { + contexts.push(context) + return 'placeholder1' + }, + }), + ) + + expect(contexts[0]!.meta).toBe(meta1) + }) + + it('should allow reading from the cache with the client inside the placeholderData function', async () => { + const listKey = queryKey() + const detailKey = queryKey() + + queryClient.setQueryData(listKey, [{ id: '1', title: 'from list' }]) + + const observer = new QueryObserver(queryClient, { + queryKey: detailKey, + queryFn: () => ({ id: '1', title: 'from detail' }), + placeholderData: (_previousData, _previousQuery, { client }) => + client + .getQueryData>(listKey) + ?.find((item) => item.id === '1'), + }) + + expect(observer.getCurrentResult()).toMatchObject({ + status: 'success', + isPlaceholderData: true, + data: { id: '1', title: 'from list' }, + }) + + const results: Array> = [] + + const unsubscribe = observer.subscribe((result) => { + results.push(result) + }) + + await vi.advanceTimersByTimeAsync(0) + unsubscribe() + + expect(results.length).toBe(2) + expect(results[0]).toMatchObject({ + isPlaceholderData: true, + data: { id: '1', title: 'from list' }, + }) + expect(results[1]).toMatchObject({ + isPlaceholderData: false, + data: { id: '1', title: 'from detail' }, + }) + }) + + it('should still support a placeholderData function that ignores the context', async () => { + const key1 = queryKey() + const key2 = queryKey() + + const observer = new QueryObserver(queryClient, { + queryKey: key1, + queryFn: () => 'data1', + placeholderData: keepPreviousData, + }) + + const results: Array> = [] + + const unsubscribe = observer.subscribe((result) => { + results.push(result) + }) + + await vi.advanceTimersByTimeAsync(0) + + observer.setOptions({ + queryKey: key2, + queryFn: () => 'data2', + placeholderData: keepPreviousData, + }) + + await vi.advanceTimersByTimeAsync(0) + unsubscribe() + + expect(results.length).toBe(4) + expect(results[2]).toMatchObject({ + data: 'data1', + status: 'success', + isPlaceholderData: true, + }) + expect(results[3]).toMatchObject({ + data: 'data2', + status: 'success', + isPlaceholderData: false, + }) + }) + it('should notify cache listeners when setOptions is called', () => { const key = queryKey() diff --git a/packages/query-core/src/queryObserver.ts b/packages/query-core/src/queryObserver.ts index 954c969d548..31b66c4a793 100644 --- a/packages/query-core/src/queryObserver.ts +++ b/packages/query-core/src/queryObserver.ts @@ -505,10 +505,20 @@ export class QueryObserver< placeholderData = typeof options.placeholderData === 'function' ? ( - options.placeholderData as unknown as PlaceholderDataFunction + options.placeholderData as unknown as PlaceholderDataFunction< + TQueryFnData, + TError, + TQueryData, + TQueryKey + > )( this.#lastQueryWithDefinedData?.state.data, - this.#lastQueryWithDefinedData as any, + this.#lastQueryWithDefinedData, + { + client: this.#client, + queryKey: options.queryKey, + meta: options.meta, + }, ) : options.placeholderData } diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index b2e80f2a144..3f1a5fd04e7 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -162,6 +162,12 @@ export type QueryFunctionContext< meta: QueryMeta | undefined } +export type PlaceholderDataContext = { + client: QueryClient + queryKey: TQueryKey + meta: QueryMeta | undefined +} + export type InitialDataFunction = () => T | undefined type NonFunctionGuard = T extends Function ? never : T @@ -174,11 +180,16 @@ export type PlaceholderDataFunction< > = ( previousData: TQueryData | undefined, previousQuery: Query | undefined, + context: PlaceholderDataContext, ) => TQueryData | undefined -export type QueriesPlaceholderDataFunction = ( +export type QueriesPlaceholderDataFunction< + TQueryData, + TQueryKey extends QueryKey = QueryKey, +> = ( previousData: undefined, previousQuery: undefined, + context: PlaceholderDataContext, ) => TQueryData | undefined export type QueryKeyHashFunction = ( diff --git a/packages/react-query/src/__tests__/useQueries.test-d.tsx b/packages/react-query/src/__tests__/useQueries.test-d.tsx index e4bd6497668..d91343fdc31 100644 --- a/packages/react-query/src/__tests__/useQueries.test-d.tsx +++ b/packages/react-query/src/__tests__/useQueries.test-d.tsx @@ -3,7 +3,13 @@ import { queryKey } from '@tanstack/query-test-utils' import { skipToken } from '..' import { useQueries } from '../useQueries' import { queryOptions } from '../queryOptions' -import type { OmitKeyof, QueryFunction, QueryKey } from '..' +import type { + OmitKeyof, + QueryClient, + QueryFunction, + QueryKey, + QueryMeta, +} from '..' import type { UseQueryOptions, UseQueryResult } from '../types' import type { QueryFunctionContext } from '@tanstack/query-core' @@ -175,6 +181,27 @@ describe('useQueries', () => { }) }) + describe('placeholderData', () => { + it('should accept queryOptions with a placeholderData function reading its context', () => { + const testQueryKey = ['SomeQuery', 42, { foo: 'bar' }] as const + + const options = queryOptions({ + queryKey: testQueryKey, + queryFn: () => 'data', + placeholderData: (_previousData, _previousQuery, context) => { + expectTypeOf(context.client).toEqualTypeOf() + expectTypeOf(context.queryKey).toEqualTypeOf() + expectTypeOf(context.meta).toEqualTypeOf() + return undefined + }, + }) + + const queryResults = useQueries({ queries: [options] }) + + expectTypeOf(queryResults[0].data).toEqualTypeOf() + }) + }) + describe('type parameters', () => { it('should handle type parameter - tuple of tuples', () => { const key1 = queryKey() diff --git a/packages/react-query/src/__tests__/useQuery.test.tsx b/packages/react-query/src/__tests__/useQuery.test.tsx index 05984e66ce5..f509ab7b6c0 100644 --- a/packages/react-query/src/__tests__/useQuery.test.tsx +++ b/packages/react-query/src/__tests__/useQuery.test.tsx @@ -23,7 +23,12 @@ import { renderWithClient, setActTimeout, } from './utils' -import type { DefinedUseQueryResult, QueryFunction, UseQueryResult } from '..' +import type { + DefinedUseQueryResult, + PlaceholderDataContext, + QueryFunction, + UseQueryResult, +} from '..' import type { Mock } from 'vitest' describe('useQuery', () => { @@ -4383,6 +4388,51 @@ describe('useQuery', () => { expect(placeholderFunctionRunCount).toEqual(1) }) + it('should provide a context with the client, queryKey and meta to the placeholder data function', async () => { + const listKey = queryKey() + const detailKey = queryKey() + const meta = { it: 'works' } + + const contexts: Array = [] + const states: Array> = [] + + queryClient.setQueryData(listKey, [{ id: '1', title: 'from list' }]) + + function Page() { + const state = useQuery({ + queryKey: [detailKey, '1'], + queryFn: () => + sleep(10).then(() => ({ id: '1', title: 'from detail' })), + meta, + placeholderData: (_previousData, _previousQuery, context) => { + contexts.push(context) + return context.client + .getQueryData>(listKey) + ?.find((item) => item.id === '1') + }, + }) + + states.push(state) + + return
title: {state.data?.title}
+ } + + const rendered = renderWithClient(queryClient, ) + + await vi.advanceTimersByTimeAsync(11) + rendered.getByText('title: from detail') + + expect(states[0]).toMatchObject({ + isPlaceholderData: true, + data: { id: '1', title: 'from list' }, + }) + + const context = contexts[0]! + expect(context.client).toBe(queryClient) + expect(context.queryKey).toEqual([detailKey, '1']) + expect(context.meta).toBe(meta) + }) + it('select should only run when dependencies change if memoized', async () => { const key1 = queryKey() diff --git a/packages/react-query/src/useQueries.ts b/packages/react-query/src/useQueries.ts index 5f5261a870e..dfc8efee280 100644 --- a/packages/react-query/src/useQueries.ts +++ b/packages/react-query/src/useQueries.ts @@ -48,7 +48,9 @@ type UseQueryOptionsForUseQueries< UseQueryOptions, 'placeholderData' | 'subscribed' > & { - placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction + placeholderData?: + | TQueryFnData + | QueriesPlaceholderDataFunction } // Avoid TS depth-limit error in case of large array literal diff --git a/packages/solid-query/src/useQueries.ts b/packages/solid-query/src/useQueries.ts index 51a2666982f..aa1ce077571 100644 --- a/packages/solid-query/src/useQueries.ts +++ b/packages/solid-query/src/useQueries.ts @@ -39,7 +39,9 @@ type UseQueryOptionsForUseQueries< QueryOptions, 'placeholderData' | 'suspense' > & { - placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction + placeholderData?: + | TQueryFnData + | QueriesPlaceholderDataFunction /** * @deprecated The `suspense` option has been deprecated in v5 and will be removed in the next major version. * The `data` property on useQueries is a plain object and not a SolidJS Resource. diff --git a/packages/svelte-query/src/createQueries.svelte.ts b/packages/svelte-query/src/createQueries.svelte.ts index 7f46ddf33ab..307311e8b93 100644 --- a/packages/svelte-query/src/createQueries.svelte.ts +++ b/packages/svelte-query/src/createQueries.svelte.ts @@ -30,7 +30,9 @@ type CreateQueryOptionsForCreateQueries< CreateQueryOptions, 'placeholderData' > & { - placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction + placeholderData?: + | TQueryFnData + | QueriesPlaceholderDataFunction } // Avoid TS depth-limit error in case of large array literal