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