泛型
介绍
泛型用来创建可重用的组件,用于支持多个数据类型;用于支持同一个组件的不同数据类型支持
Hallo world
function identity<T>(arg:T):T{
return arg
}
该例子输入任意一个类型的变量并返回,但一般情况并不会使用
let output = identity<string>("myString"); // type of output will be 'string'
而是更多使用类型推断
let output = identity("myString"); // type of output will be 'string'
泛型变量
将泛型作为类型的一部分进行使用而不是全部,增加了灵活性
举例
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
//等价
function loggingIdentity<T>(arg: Array<T>): Array<T> {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
传入该函数的是T类型的数组,并且返回该数组。这样能在函数内部输出传入类型的长度。
泛型类型
泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样:
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = identity;
同理,我们就可以写泛型接口了,举例如下:
interface identifun_face {
<T>(arg :T):T;
}
function identity<T>(arg: T) :T{
return arg;
}
let newfun:identifun_face = identity;
//newfun实现了接口identifun_face
也可以将泛型当作整个接口的一个参数,这样接口中的其他成员也能知道泛型的类型
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
//注意,此时的接口在实现时锁定了泛型的类型,而上面将泛型放在成员中就不会有这样的问题
泛型类
泛型类与泛型接口类似,但是注意,官方文档的例子会报错
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
//报错为:Property 'zeroValue' has no initializer and is not definitely assigned in the constructor.
//Property 'add' has no initializer and is not definitely assigned in the constructor.
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
报错原因是类中的属性未进行初始化,需要对例子进行修改才能达到类似的效果。
(PS:认为是2.7版本后的编译器新增选项,对类进行初始化检查,而官网没有及时更新)
参考:https://www.jianshu.com/p/7d829bdac875
修改为
class Generic<T> {
// zeroValue: T;
// add: (x: T, y: T) => T;
constructor(public zeroValue: T, public add: (x: T, y: T) => T) {
this.zeroValue = zeroValue;
this.add = add;
}
}
let myGenericNumber = new Generic<number>(0, (a, b) => a + b);
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) { return x + y; };
const result = myGenericNumber.add(40, 2) // 42