前言
TypeScript泛型
一、何时用到?
举例, 一个函数必须接受两个同类型的参数, 然后会将二者组成数组返回, 基本是这样:
function toArray(zero: Number, first: Number): Number[] {
return [zero, first];
}
但这样是不是存在问题呢, 规则是该函数应该接受两个同类型参数, 上面的函数能接受两个String吗?
接受不能吧, 很蓝的啦, 除非你写AnyScript:
function toArray(zero: any, first: any): any[] {
return [zero, first];
}
或者JavaScript, 但那又无法保证两参数类型一致了.
使用泛型可以解决这个问题, 让这个函数的功能达到预期.
所以说泛型创建可重用的, 不仅能支持目前的数据类型, 也能支持将来的数据类型的结构.
二、泛型写法
1.函数Function + 泛型
所以你可以简单理解泛型就是泛用类型, 某不确定类型需要被泛用, JavaScript内有’魔术字符串’的概念, 为了避免该现象会将魔术字符串存到变量内, 这样以后需要修改字符串的话只需修改一个变量即可了.
同样的你要在各处使用类型, 就把类型看成魔术字符串, 如果你要统一控制到这些类型, 就把类型存进变量.
比如用变量T来存储Number类型, 然后在需要表明类型的地方使用变量T, 就可以在多处统一表明Number类型, 同样的如果T是其他类型, 也可以做到各处的类型统一.
先看看官方介绍的泛型写法:
function identity<T>(zero: T, first: T): T[] {
return arg;
}
identity<string>("myString");
把T看作变量, 这个变量由调用identity函数时尖括号内的值赋值, 上例中T被赋值为String.
然后两参数zero和first都是T类型, 即都是String类型.
那么就可以做到两参数的类型统一.
也难免会遇到需要多个像T这样的变量的情况:
const test = function <T, U>(zero: U, first: T): (U | T)[] {
return [zero, first];
};
test<string, number>(1, '啊');
那么增加一个类型变量U.
尖括号内的T, U, 和形式参数T, U不需要在顺序方面有对应关系.
但是调用函数时尖括号内的类型和函数尖括号内的类型变量是对应的, 不要搞错.
2.接口interface + 泛型
仍旧把泛型看作变量, getFullName函数的返回值由checkFullName进行检测, 必须存在T类型的namea, 和C类型的nameb.
interface checkFullName