可以使用
泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件
基本概念
现在有个函数返回传入参数本身
function test(x:number):number{
return x
}
console.log(test(1)) //1
那假如我想给他传入string类型的我们可能需要重新定义一个函数
function test(x:string):string{
return x
}
console.log(test('test')) //test
这样下去函数的复用性就变得很差,我们可以使用泛型来做改造
function test<T>(x:T):T{
return x
}
console.log(test<number>(1)) //1
console.log(test<string>('test')) //test
这样我们就可以在调用的时候手动指定类型来达到复用的效果
泛型类型
我们可以使用接口来接受一个泛型,下面继续改造一下上面的例子
interface testFace<T> {
(arg: T): T;
}
let myTest: testFace<number>=x=>x;
console.log(myTest(1)) //1
泛型类
我们同样可以使用泛型来约束类
class Test<T> {
num: T;
constructor(num: T){
this.num=num
}
add(x: T): T {
return x;
}
}
console.log(new Test<number>(1).add(1))
泛型约束
我们把最开始的例子加一个需求,我们需要在函数里面拿到传入参数的length属性
function test<T>(x:T):T{
console.log(x.length) //类型T上不存在length属性
return x
}
test<string>('test')
虽然我们传入了string类型是有length属性的,但是编译器并不能证明每种类型都有length属性,所以就报错了。
interface testFace{
length:number
}
function test<T extends testFace>(x:T):T{
console.log(x.length)
return x
}
test<string>('test')
在上面的例子上我们声明了一个类型里面有length属性并且让类型T继承了该属性,解决了问题
函数参数使用类
class test{}
function create<T>(c: {new(): T}): T {
return new c();
}
create(test)
或者说
class test{}
interface testFace<T>{
new():T
}
function create<T>(c: testFace<T>): T {
return new c();
}
create(test)