业务场景
当我们封装一个 ajax 请求,其本质是异步 Promise 的调用。
我们可以写一个高阶函数,在 Promise 的 executor 前展示 loading 提示,在请求结束后关闭 loading 提示。
这样,我们会得到如下requestLoadingWrapper
的实现。
JS 实现
ajaxFunc(示例)
1 | export const getUserInfo = async () => |
requestLoadingWrapper
1 | function requestLoadingWrapper (fn) { |
以上,看似很简单,但是如果我们对 TS 的基础不太熟悉或者不够深入的话,写起来还是无从下手的。这样,我们来重温下 TS 的一些基础
重拾 TS 基础
条件类型 - extends 关键字
extends 用于条件判断中,其作用类似为 js 的 typeof 关键字。
注意:extends 运用在 type 和 class 中时完全是两种作用的效果
直接看例子
1 | type TypeName<T> = T extends string |
有趣的实现:PowerPartial
使用递归,将 object 每一层的参数都转化为可选。
1 | type PowerPartial<T> = { |
infer 关键字
用法:在条件类型语句中, 可以用 infer
声明一个类型变量并且对它进行使用。
- 这里顺便就可以重温下 TS 中
ReturnType
的实现,
ReturnType
,意思是获取 Function 类型的返回值类型。
1 | type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any |
- 类似地,
Parameter
的实现也大同小异
1 | // node_modules/typescript/lib/lib.es5.d.ts |
- 还有
ConstructorParameter
,获取构造函数的参数
1 | // node_modules/typescript/lib/lib.es5.d.ts |
- 还有
InstanceType
,获取构造函数的实例类型
1 | // node_modules/typescript/lib/lib.es5.d.ts |
TS 实现
获取 Promise 的返回值类型
利用条件类型和 infer
关键字,我们还可以方便地实现获取 Promise 对象的返回值类型
1 | type Unpacked<T> = T extends Promise<infer P> ? P : T |
提取传入函数的参数和返回值
1 | export function requestLoadingWrapper<T extends (...args: any[]) => any>( |
使用
1 | export const getUserInfo = async () => |