Lopais
Lopais3w ago

Type stable "combine" function for "useQueries"

Hey all, im trying to use a https://tanstack.com/query/latest/docs/framework/react/reference/useQueries#combine function to combine the results from multiple queries together. As the documentation says, the combine function should be referentially stable. Im trying to get this typed properly, but getting the proper type for the "result" parameter of the combine function is a little crazy the way I have it working now, see example below. I must be missing something obvious to make this less crazy, any tips? Thanks! ❤️
const trpc = useTRPC();

// Stable reference to the "combine" function
const combineData = useCallback(
(
// --- THIS IS CRAZY ---
result: Parameters<
Exclude<
Parameters<
typeof useQueries<
Array<
ReturnType<typeof trpc.projects.plannedTime.get.queryOptions>
>
>
>[0]["combine"],
undefined
>
>[0],
) => return result.flatMap((r) => r.data ?? []),
[trpc],
);

const data = useQueries({
queries: sections.map((section) =>
trpc.projects.plannedTime.get.queryOptions({
projectId,
startDate: section.start,
endDate: section.end,
}),
),
combine: combineData,
});
const trpc = useTRPC();

// Stable reference to the "combine" function
const combineData = useCallback(
(
// --- THIS IS CRAZY ---
result: Parameters<
Exclude<
Parameters<
typeof useQueries<
Array<
ReturnType<typeof trpc.projects.plannedTime.get.queryOptions>
>
>
>[0]["combine"],
undefined
>
>[0],
) => return result.flatMap((r) => r.data ?? []),
[trpc],
);

const data = useQueries({
queries: sections.map((section) =>
trpc.projects.plannedTime.get.queryOptions({
projectId,
startDate: section.start,
endDate: section.end,
}),
),
combine: combineData,
});
useQueries | TanStack Query React Docs
The useQueries hook can be used to fetch a variable number of queries: tsx const ids = [1, 2, 3] const results = useQueries({ queries: ids.map((id) = ({ queryKey: ['post', id], queryFn: () = fetchPost...
5 Replies
Nick
Nick3w ago
Sounds like the inferrence helpers are really what you want: https://trpc.io/docs/client/tanstack-react-query/usage#inferring-input-and-output-types
TanStack React Query | tRPC
TanStack React Query usage
Nick
Nick3w ago
you might also find typescript works fine calling useCallback as the parameter to the combine function. Not 100% sure on that but it often does infer types quite cleverly
Lopais
LopaisOP3w ago
Thanks Nick! I was trying the Inference helpers for a long time, it seems the combine "result" is the full queries, not the the input/output type, so I didn't get a working solution with these. Great idea on using useCallback directly, but sadly it doesn't infer the type properly
No description
Lopais
LopaisOP3w ago
Figured it out, QueriesResults was the trick:
import {
QueriesResults,
useQueries,
} from "@tanstack/react-query";

const combineData = useCallback(
(
result: QueriesResults<
Array<ReturnType<typeof trpc.projects.plannedTime.get.queryOptions>>
>,
) => {
return result.flatMap((r) => r.data ?? []);
},
[trpc],
);

const data = useQueries({
queries: sections.map((section) =>
trpc.projects.plannedTime.get.queryOptions({
projectId,
startDate: section.start,
endDate: section.end,
}),
),
combine: combineData,
});
import {
QueriesResults,
useQueries,
} from "@tanstack/react-query";

const combineData = useCallback(
(
result: QueriesResults<
Array<ReturnType<typeof trpc.projects.plannedTime.get.queryOptions>>
>,
) => {
return result.flatMap((r) => r.data ?? []);
},
[trpc],
);

const data = useQueries({
queries: sections.map((section) =>
trpc.projects.plannedTime.get.queryOptions({
projectId,
startDate: section.start,
endDate: section.end,
}),
),
combine: combineData,
});
Nick
Nick3w ago
Glad you solved it! Yes that looks like the best way

Did you find this page helpful?