TypeScript中是否可在泛型参数中使用展开运算符批量传参?
问题解答
TypeScript 截至5.x正式版本,不支持在泛型传参位置直接使用...展开运算符传入元组类型批量赋值给多个泛型形参,你写的useQuery<...QueryTypeParams>属于非法语法。你看到的Variable 'QueryTypeParams' implicitly has an 'any' type报错,是TS解析该非法语法失败后抛出的衍生错误,不是QueryTypeParams本身的类型定义有问题。
可以通过以下方式实现批量传递泛型参数的需求:
方案1:定义类型固定的包装函数(推荐)
通过类型断言把原生useQuery断言为绑定了你预设泛型参数的版本,没有额外运行时代码,完全零开销:
import { useQuery, QueryKey } from '@tanstack/react-query' // 预设的泛型参数,顺序必须和原生useQuery的泛型定义一一对应 type QueryTypeParams = [Record<string, number>, unknown, unknown, "aKey" as const] // 生成绑定了固定泛型的useQuery版本 const useFixedTypeQuery = useQuery as < TQueryFnData = QueryTypeParams[0], TError = QueryTypeParams[1], TData = QueryTypeParams[2], TQueryKey extends QueryKey = QueryTypeParams[3] >( ...args: Parameters<typeof useQuery<TQueryFnData, TError, TData, TQueryKey>> ) => ReturnType<typeof useQuery<TQueryFnData, TError, TData, TQueryKey>> // 使用时会自动套用你预设的泛型约束 const { data } = useFixedTypeQuery( "anotherKey", // 此处TS会抛出类型错误,符合预期 () => ({ test: 1 }) )
方案2:按元组索引传入泛型参数
如果不想额外定义包装函数,也可以在调用时按顺序取元组对应位置的类型传入泛型列表,效果完全一致:
const {data} = useQuery<QueryTypeParams[0], QueryTypeParams[1], QueryTypeParams[2], QueryTypeParams[3]>( "anotherKey", // 此处同样会抛出类型错误 () => ({ test: 1 }) )
注意事项
- 预设泛型参数的顺序必须和原方法的泛型定义顺序严格对齐,顺序错位会导致类型约束完全失效
- 如果不需要固定全部泛型,可以只给需要固定的位置赋值,其余位置保留原方法的默认类型即可
内容的提问来源于stack exchange,提问作者Hiroki Yokoiwa
相关产品推荐
相关产品推荐

