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

86 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 函数
};
}