doctor-mail/packages/client/src/api/hooks/useEntity.ts

86 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-01-25 00:37:59 +08:00
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 函数
};
}