import type { UseTRPCMutationResult } from "@trpc/react-query/shared"; import { api, type RouterInputs, type RouterOutputs } from "../trpc"; /** * 定义 MutationType 类型,用于提取指定实体类型的特定 mutation 方法名。 * @template T - 实体类型的键名(如 'post', 'user') * @description 该类型通过遍历 RouterInputs[T] 的键名,筛选出符合条件的 mutation 方法名(如 'create', 'update' 等)。 */ type MutationType = keyof { [K in keyof RouterInputs[T]]: K extends "create" | "update" | "deleteMany" | "softDeleteByIds" | "restoreByIds" | "updateOrder" ? RouterInputs[T][K] : never }; /** * 定义 MutationOptions 类型,用于配置特定 mutation 方法的回调函数。 * @template T - 实体类型的键名 * @template K - mutation 方法名 * @description 该类型包含一个可选的 onSuccess 回调函数,用于在 mutation 成功时执行。 */ type MutationOptions> = { onSuccess?: ( data: RouterOutputs[T][K], // mutation 成功后的返回数据 variables: RouterInputs[T][K], // mutation 的输入参数 context?: unknown // 可选的上下文信息 ) => void; }; /** * 定义 EntityOptions 类型,用于配置实体类型的所有 mutation 方法的回调函数。 * @template T - 实体类型的键名 * @description 该类型是一个对象,键为 mutation 方法名,值为对应的 MutationOptions 配置。 */ type EntityOptions = { [K in MutationType]?: MutationOptions; }; /** * 工具类型:简化 UseTRPCMutationResult 的类型断言。 * @template T - 实体类型的键名 * @template K - mutation 方法名 * @description 该类型用于简化 UseTRPCMutationResult 的类型定义,使其更易读。 */ type MutationResult> = UseTRPCMutationResult< RouterOutputs[T][K], // mutation 成功后的返回数据 unknown, // mutation 的错误类型 RouterInputs[T][K], // mutation 的输入参数 unknown // mutation 的上下文类型 >; /** * 自定义 Hook:用于处理实体的 mutation 操作,并内置缓存失效机制。 * @template T - 实体类型的键名(如 'post', 'user') * @param {T} key - 实体键名 * @param {EntityOptions} [options] - 可选的 mutation 回调函数配置 * @returns 返回一个包含多个 mutation 函数的对象 * @description 该 Hook 封装了常见的 mutation 操作(如 create, update, deleteMany 等),并在每次 mutation 成功后自动失效相关缓存。 */ export function useEntity(key: T, options?: EntityOptions) { const utils = api.useUtils(); // 获取 tRPC 的工具函数,用于操作缓存 /** * 创建 mutation 处理函数。 * @template K - mutation 方法名 * @param {K} mutation - mutation 方法名 * @returns 返回一个配置好的 mutation 函数 * @description 该函数根据传入的 mutation 方法名,生成对应的 mutation 函数,并配置 onSuccess 回调。 */ const createMutationHandler = >(mutation: K) => { const mutationFn = (api[key as any])[mutation]; // 获取对应的 tRPC mutation 函数 return mutationFn.useMutation({ onSuccess: (data, variables, context) => { utils[key].invalidate(); // 失效指定实体的缓存 options?.[mutation]?.onSuccess?.(data, variables, context); // 调用用户自定义的 onSuccess 回调 }, }); }; // 返回包含多个 mutation 函数的对象 return { create: createMutationHandler("create") as MutationResult, // 创建实体的 mutation 函数 update: createMutationHandler("update") as MutationResult, // 更新实体的 mutation 函数 deleteMany: createMutationHandler("deleteMany") as MutationResult, // 批量删除实体的 mutation 函数 softDeleteByIds: createMutationHandler("softDeleteByIds") as MutationResult, // 软删除实体的 mutation 函数 restoreByIds: createMutationHandler("restoreByIds") as MutationResult, // 恢复软删除实体的 mutation 函数 updateOrder: createMutationHandler("updateOrder") as MutationResult, // 更新实体顺序的 mutation 函数 }; }