我正在尝试创建一个包装函数,它接受一个查询和一个化简器,然后返回本质上相同的函数,但有一个附加属性 ( ) 包含_data
查询数据的处理版本(具体来说,我想转换查询结果到Immutable.js记录)。
我希望此函数对任何可能的查询都是通用的,并保留查询中的调用签名和类型信息。我试图通过使用Parameters<typeof queryHook>
和来做到这一点ReturnType<typeof queryHook>
。但是,当我将参数传递给queryHook
内部函数时,Typescript 抱怨说参数不能分配给内部函数,即使它们应该从该函数的参数中键入。
我的问题是,为什么 Typescript 不能告诉传递给包装查询的参数应该与查询的预期参数具有相同的类型?
目前,它给出了一个错误,表明可能queryHook
是任何可能的查询,而不是传递给函数的特定查询。
奇怪的是,如果我真的使用这个函数,所有类型都会被正确推断出来……
我的代码如下:
/** List of all possible hooks to wrap */
type AllQueryHooks = typeof useGetPaymentsQuery | typeof useGetAddressesQuery
/**
* @param queryHook GraphQL query to wrap
* @param reducer Function to transform GraphQL result. Return value will be
* available on the _data prop
*/
export function wrapGQLHook<T, Hook extends AllQueryHooks>(
queryHook: Hook,
reducer: (data: ReturnType<typeof queryHook>['data']) => T,
): (
...args: Parameters<typeof queryHook>
) => ReturnType<typeof queryHook> & { _data: T | undefined } {
function wrappedGQLHook(...args: Parameters<typeof queryHook>) {
const queryResult = queryHook(...args)
// ...args is overloaded ^^^^^^^
let _data: T | undefined = undefined
if (queryResult.data) {
_data = reducer(queryResult.data)
}
return { ...queryResult, _data }
}
return wrappedGQLHook
// ^^^^^^^^^^^^^^ not assignable to ReturnType<Hook>
}
/**
* Wrapped useGetPaymentsQuery hook
*
* Returns useGetPaymentsQuery vars, plus a _data prop containing a List of
* PaymentRecords
*/
export const useGetPaymentsQueryWrapped = wrapGQLHook(
useGetPaymentsQuery,
(data) => {
if (!data) return
const { Payments } = data
return Payments.edges.map((node) => node)
// ^^^^^^^^^^^^ return type inferred correctly ¯\_(ツ)_/¯
},
)
慕仙森
相关分类