泛型从入门到骚操作
Chunbin Lv4

泛型可以用来创建可重用的数据类型

显式指定

以Array为例子

1
2
3
4
5
const numberArr:Array<number> = [1]  // 显式指定了数组为number类型
const stringArr:Array<string> = ['1'] // 显式指定了数组为number类型

stringArr.push('2'); // 无报错
stringArr.push(2); // ts:类型“2”的参数不能赋给类型“string”的参数。

类型推论

除了显示指定类型,编译器会根据传入的参数自动地帮助我们确定泛型T的类型

1
2
3
4
5
6
7
8
9
10
function returnAll<T>(param: T): T {
return param;
}

interface IProps {
color: string;
size: string;
}
const props: IProps = { color: 'white', size: '12px' };
const test = returnAll(props); // const test: IProps 推断出了test为IProps

可以观察到,我们并没有给方法显式的指定类型,但是参数指定了类型,编译器相当于把T做了一个链接,把参数的类型作为T,然后其他地方也可以使用T,所以返回参数也能以T为返回参数参数类型

开始我们的骚操作

有了以上两点,我们就可以写出一些困难的推导

推导出参数的Promise的返回值

应用场景:常见的网络请求库,接收一个Promise作为参数,结果产生了类型丢失
解决方案:使用类型推论+泛型+infer做推导

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

type A = Promise<number>;

const a: A = new Promise(resolve => {
setTimeout(() => {
resolve(12);
}, 0);
});

function getParamType<T>(param: T): T extends Promise<infer R> ? R : T;
function getParamType(params) {
params.then(res => {
return res;
});
}

const res = getParamType(a); // const res: number 推断成功

关键语法

1
function getParamType<T>(param: T): T extends Promise<infer R> ? R : T;

要点:

  • 使用泛型获取参数的类型T
  • 使用extends判断类型T是否为Promise类型
  • 使用infer R指定待推断的类型,并提取出来R
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量