从一个复杂的泛型参数的函数签名深入理解typescript关于泛型的类型推断

 以下是nuxt3中useFetch的函数签名,看起来很长有点乱对不对,但这还是我优化格式后的结果,不然更难看(原始的代码是在同一行里显示),泛型参数部分看红色的左右尖括号里的部分(各个泛型参数用红色的逗号隔开),

export declare function useFetch<ResT = void, ErrorT = FetchError,

ReqT extends NitroFetchRequest = NitroFetchRequest,

Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,

_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,

DataT = _ResT,

PickKeys extends KeysOf<DataT> = KeysOf<DataT>,

DefaultT = null>(request: Ref<ReqT> | ReqT | (() => ReqT), opts?: UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT,  ErrorT | null>;

 这里重点通过类型推导说明:为什么ResT 就一定是useFetch的返回类型

 首先看最后一行的返回值类型:

 AsyncData<PickFrom<DataT, PickKeys> | DefaultT,  ErrorT | null>

这也是一个泛型,首先不考虑外围AsyncData的包装,它直接跟PickFrom里面的有关系,

从字面意思也可以理解到PickFrom是:从DataT类型中挑选出key值为PickKeys所对应的类型,

那么基本可以断定AsyncData的类型最终跟DataT的类型有关

 而泛型参数列表中有个定义:DataT = _ResT,就是说DataT类型取决于_ResT

而_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT

这句话的意思是如果ResT类型为空,则_ResT类型为FetchResult<ReqT, Method>,否则_ResT类型就是ResT, 一句话_ResT类型取决于ResT的类型。

所以根据链式关系: DataT =》 _ResT =》 ResT,可以得出:  DataT类型取决于 ResT的类型

AsyncData的类型最终跟DataT的类型有关,所以AsyncData类型也取决于ResT的类型

所以ResT的类型就是useFetch函数的返回类型

但这还不够,需要继续深挖,证明这个结论==》AsyncData的类型取决于DataT的类型

对于PickFrom<DataT, PickKeys>,我们不去深究,这个基本可以判断:必定取决于DataT类型

重点要看AsyncData部分的定义

export interface _AsyncData<DataT, ErrorT> {

    data: Ref<DataT>;

    pending: Ref<boolean>;

    refresh: (opts?: AsyncDataExecuteOptions) => Promise<DataT>;

    execute: (opts?: AsyncDataExecuteOptions) => Promise<DataT>;

    error: Ref<ErrorT | null>;

    status: Ref<AsyncDataRequestStatus>;

}

export type AsyncData<Data, Error> = _AsyncData<Data, Error> & Promise<_AsyncData<Data, Error>>;

从上面的代码可以看到:AsyncData取决于_AsyncData,而_AsyncData的类型的真正数据是data属性,而data正是AsyncData的第一个泛型参数:Data, 而Data相当于上面的

PickFrom<DataT, PickKeys> | DefaultT, 这个值直接跟DataT类型有关

所以这里就证明了: AsyncData的类型确实取决于DataT的类型,而 DataT类型又取决于 ResT的类型,所以 AsyncData的类型最终取决于ResT的类型,而AsyncData是useFetch函数返回值类型,那么可以推断出==》ResT类型就是useFetch函数的返回值类型

相关推荐

  1. typescript

    2023-12-23 09:26:02       13 阅读
  2. 理解typescript

    2023-12-23 09:26:02       10 阅读
  3. TypeScript 类型

    2023-12-23 09:26:02       12 阅读
  4. 之广泛类型

    2023-12-23 09:26:02       13 阅读
  5. TypeScript函数

    2023-12-23 09:26:02       47 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-23 09:26:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-23 09:26:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-23 09:26:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-23 09:26:02       20 阅读

热门阅读

  1. react 2

    react 2

    2023-12-23 09:26:02      33 阅读
  2. centos 7.4 docker

    2023-12-23 09:26:02       37 阅读
  3. 在CentOS 7上使用普通用户`minio`安装和配置MinIO

    2023-12-23 09:26:02       34 阅读
  4. K-means 算法 简介

    2023-12-23 09:26:02       35 阅读
  5. Valgrind:查找内存泄漏

    2023-12-23 09:26:02       38 阅读
  6. 基于SVM的鸟鸣识别,语谱分析

    2023-12-23 09:26:02       36 阅读
  7. mybatisPlus 常见用法

    2023-12-23 09:26:02       31 阅读
  8. 【小白专用】HTML相对路径表示方法

    2023-12-23 09:26:02       31 阅读