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

如何为trpc.useQuery包装器的首个参数定义精确泛型类型?

解决TRPC useQuery包装器的泛型类型定义问题

正确的类型定义方案

直接复用TRPC useQuery 本身的参数类型,避免手动判断输入是否可选,就能完美解决类型不匹配的问题:

import type { UseQueryResult } from "react-query";
import type { inferProcedureOutput, inferProcedureInput } from "@trpc/server";

type TQuery = keyof AppRouter["_def"]["queries"];

type inferQueryInput<TRouteKey extends TQuery> = inferProcedureInput<
  AppRouter["_def"]["queries"][TRouteKey]
>;

type inferQueryOutput<TRouteKey extends TQuery> = inferProcedureOutput<
  AppRouter["_def"]["queries"][TRouteKey]
>;

// 包装器实现
function useIndexedTRpcQuery<TRouteKey extends TQuery>(
  pathAndInput: Parameters<typeof trpc.useQuery<TRouteKey>>[0]
): UseQueryResult<inferQueryOutput<TRouteKey>> {
  // 这里添加你的自定义逻辑
  const result = trpc.useQuery(pathAndInput);
  
  // 示例:自定义处理逻辑,比如打印查询路径
  console.log("Query path:", pathAndInput[0]);
  
  return result;
}

为什么之前的写法会报错

  1. 第一种条件类型写法:
    你通过条件类型限定参数为单元素或双元素数组,但TypeScript无法在函数内部窄化泛型对应的具体类型分支,导致传递给trpc.useQuery时出现类型不匹配错误。

  2. 第二种可选元组写法:
    你定义的[TRouteKey, args?: inferQueryInput<TRouteKey>]是带可选元素的元组类型,而TRPC的useQuery第一个参数是联合元组类型([TRouteKey] | [TRouteKey, inferQueryInput<TRouteKey>]),两者在类型系统中不兼容,因此出现匹配失败的错误。

另一种手动类型定义方案

如果不想直接复用TRPC的参数类型,也可以手动构建正确的联合元组类型:

function useIndexedTRpcQuery<TRouteKey extends TQuery>(
  pathAndInput: 
    | [TRouteKey]
    | [TRouteKey, inferQueryInput<TRouteKey>]
): UseQueryResult<inferQueryOutput<TRouteKey>> {
  return trpc.useQuery(pathAndInput as any);
}

这里需要用as any断言是因为TypeScript对联合元组的类型推断存在局限性,无法自动确认传入的元组与TRPC内部类型完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:25:06