如何为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; }
为什么之前的写法会报错
第一种条件类型写法:
你通过条件类型限定参数为单元素或双元素数组,但TypeScript无法在函数内部窄化泛型对应的具体类型分支,导致传递给trpc.useQuery时出现类型不匹配错误。第二种可选元组写法:
你定义的[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
相关产品推荐
相关产品推荐

