You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为tRPC的useQuery封装带正确TypeScript类型的自定义Hook

解决tRPC封装useQuery自定义Hook的TypeScript类型问题

核心思路

要封装tRPC的useQuery,关键是精准识别仅支持查询操作的Procedure类型,通过泛型自动提取输入参数和返回值的类型,彻底替代any来保留类型提示。

类型安全的Hook实现

// 筛选出具备useQuery方法的Query Procedure类型,排除Mutation/Subscription等不兼容类型
type TrpcQueryProcedure = {
  useQuery: (...args: any[]) => any;
};

// 自定义Hook的类型安全版本
function useCustomHook<TProc extends TrpcQueryProcedure>(
  procedure: TProc,
  input: Parameters<TProc['useQuery']>[0]
) {
  return procedure.useQuery(input);
}

更精细化的类型推导(可选)

如果需要明确提取输入和输出的类型定义,可以进一步扩展泛型:

// 提取Query Procedure的输入参数类型
type QueryInput<TProc extends TrpcQueryProcedure> = 
  Parameters<TProc['useQuery']>[0];

// 提取Query Procedure的返回值类型
type QueryOutput<TProc extends TrpcQueryProcedure> = 
  ReturnType<TProc['useQuery']>;

function useCustomHook<TProc extends TrpcQueryProcedure>(
  procedure: TProc,
  input: QueryInput<TProc>
): QueryOutput<TProc> {
  return procedure.useQuery(input);
}

报错原因解析

  1. "TrpcProcedure无useQuery属性":你之前用了tRPC的通用Procedure类型,它包含了Mutation、Subscription等不具备useQuery的类型,必须通过存在性检查筛选出仅支持查询的子集。
  2. "联合类型签名不兼容":泛型约束过于宽泛,没有限定到useQuery的调用签名,上面的TrpcQueryProcedure通过过滤不兼容类型,避免了联合类型的冲突。

使用示例

// 调用时自动获得完整类型提示
const { data, isLoading } = useCustomHook(trpc.myendpoint, { foo: 'bar' });
// data自动匹配trpc.myendpoint的返回类型,input参数会有严格的类型校验

内容的提问来源于stack exchange,提问作者Thomas Dondorf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:28:12