import { QueryKey, UseQueryOptions } from "@tanstack/react-query" export type TQueryKey = { all: readonly [TKey] lists: () => readonly [...TQueryKey["all"], "list"] list: ( query?: TListQuery ) => readonly [...ReturnType["lists"]>, { query: TListQuery }] details: () => readonly [...TQueryKey["all"], "detail"] detail: ( id: TDetailQuery, query?: TListQuery ) => readonly [ ...ReturnType["details"]>, TDetailQuery, { query: TListQuery } ] } 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 ? { query } : undefined].filter( (k) => !!k ), details: () => [...queryKeyFactory.all, "detail"], detail: (id: TDetailQueryType, query?: TListQueryType) => [...queryKeyFactory.details(), id, query ? { query } : undefined].filter( (k) => !!k ), } return queryKeyFactory }