import { QueryKey, UseQueryOptions } from "@tanstack/react-query" type TQueryKey = { all: readonly [TKey] lists: () => readonly [...TQueryKey["all"], "list"] list: ( query?: TListQuery ) => readonly [ ...ReturnType["lists"]>, { query: TListQuery | undefined }, ] details: () => readonly [...TQueryKey["all"], "detail"] detail: ( id: TDetailQuery, query?: TListQuery ) => readonly [ ...ReturnType["details"]>, TDetailQuery, { query: TListQuery | undefined }, ] } export type UseQueryOptionsWrapper< // Return type of queryFn TQueryFn = unknown, // Type thrown in case the queryFn rejects E = Error, // Query key type TQueryKey extends QueryKey = QueryKey, > = Omit< UseQueryOptions, "queryKey" | "queryFn" > export const queryKeysFactory = < T, TListQueryType = any, TDetailQueryType = string, >( globalKey: T ) => { const queryKeyFactory: TQueryKey = { all: [globalKey], lists: () => [...queryKeyFactory.all, "list"], list: (query?: TListQueryType) => [...queryKeyFactory.lists(), { query }], details: () => [...queryKeyFactory.all, "detail"], detail: (id: TDetailQueryType, query?: TListQueryType) => [ ...queryKeyFactory.details(), id, { query }, ], } return queryKeyFactory }