以下是nuxt3中useFetch的函数签名,看起来很长有点乱对不对,但这还是我优化格式后的结果,不然更难看(原始的代码是在同一行里显示),泛型参数部分看红色的左右尖括号里的部分(各个泛型参数用红色的逗号隔开),
export declare function useFetch<ResT = void, ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod
= ResT extends void ? 'get' extends AvailableRouterMethod ? 'get' : AvailableRouterMethod : AvailableRouterMethod , _ResT = ResT extends void ? FetchResult
: ResT, DataT = _ResT,
PickKeys extends KeysOf
= KeysOf , DefaultT = null>(request: Ref
| ReqT | (() => ReqT), opts?: UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>): AsyncData | DefaultT, ErrorT | null>;
这里重点通过类型推导说明:为什么ResT 就一定是useFetch的返回类型
首先看最后一行的返回值类型:
AsyncData
这也是一个泛型,首先不考虑外围AsyncData的包装,它直接跟PickFrom里面的有关系,
从字面意思也可以理解到PickFrom是:从DataT类型中挑选出key值为PickKeys所对应的类型,
那么基本可以断定AsyncData的类型最终跟DataT的类型有关
而泛型参数列表中有个定义:DataT = _ResT,就是说DataT类型取决于_ResT
而_ResT = ResT extends void ? FetchResult
这句话的意思是如果ResT类型为空,则_ResT类型为FetchResult
所以根据链式关系: DataT =》 _ResT =》 ResT,可以得出: DataT类型取决于 ResT的类型,
而AsyncData的类型最终跟DataT的类型有关,所以AsyncData类型也取决于ResT的类型,
所以ResT的类型就是useFetch函数的返回类型
但这还不够,需要继续深挖,证明这个结论==》AsyncData的类型取决于DataT的类型
对于PickFrom
重点要看AsyncData部分的定义:
export interface _AsyncData
{ data: Ref
; pending: Ref
; refresh: (opts?: AsyncDataExecuteOptions) => Promise
; execute: (opts?: AsyncDataExecuteOptions) => Promise
; error: Ref
; status: Ref
; }
export type AsyncData = _AsyncData & Promise<_AsyncData>;
从上面的代码可以看到:AsyncData取决于_AsyncData,而_AsyncData的类型的真正数据是data属性,而data正是AsyncData的第一个泛型参数:Data, 而Data相当于上面的
PickFrom
所以这里就证明了: AsyncData的类型确实取决于DataT的类型,而 DataT类型又取决于 ResT的类型,所以 AsyncData的类型最终取决于ResT的类型,而AsyncData是useFetch函数返回值类型,那么可以推断出==》ResT类型就是useFetch函数的返回值类型