TypeScript学习笔记之 泛型

什么是泛型
泛型的本质是参数化类型,通俗的将就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法的创建中,分别成为泛型类,泛型接口、泛型方法。
TypeScript中的泛型跟java中的泛型基本类似。

泛型的基本使用
使用泛型的好处不仅能够检查类型,保证类型正确,而且能够提高代码的服用性。指定泛型类型一般用来表示,当然,T可以更改为其他值。

/**
 * Created by yzq on 2017/1/17.
 */

/*假如我们有个方法  需要返回传进去的参数 */

// function returnVal(x: number): number {
//     return x;
// }
// returnVal(1);//不使用泛型的话这里只能传进去number类型

/*这里使用any虽然可以传进去任何类型的值 但是无法保证返回值就是传进去的参数值*/
// function returnVal(x: any): any {
//     return "" + x;
// }
//
// returnVal(1);
/*这里使用泛型  不仅可以传任何类型的值  也能保证返回值类型的正确性  而且代码可以复用*/
function returnVal<T>(x: T): T {
    return x;
}
returnVal<number>(1);
returnVal("1");
returnVal(true);

泛型数组
需要注意的是,在java中由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的。所以为了防止出现类型转换异常,Java是 不支持泛型数组的。
而在TypeScript中支持泛型数组。当我们将参数类型指定为泛型数组,那么,也就代表着这个参数具有数组的所有属性和方法。

/*这里使用泛型  不仅可以传任何类型的值  也能保证返回值类型的正确性  而且代码可以复用*/
function returnVal<T>(x: T): T {
    //console.log(x.length);//这里的参数可能是number或boolean,所以没有.length属性
    return x;
}
returnVal<number>(1);
returnVal("1");
returnVal(true);

function Arr<T>(arg: T[]): T[] {
    console.log(arg.length);//这里的泛型数组,那么参数就会有数组所具有的属性和方法
    arg.join("333");
    return arg;
}
let a:Array<string>=["a","b"];
Arr(a);
Arr<string>(["1","2","a"]);

泛型方法

function A<T>(arg: T): T {
    return arg;
}
// let funA:(a:string)=>string=A;
let funA:(a:number)=>number=A;
// funA("1");
funA(1);

/*我们还可以使用带有调用签名的对象字面量来定义泛型函数:*/
let funA1:{<T>(arg:T):T}=A;

泛型接口

interface GenericIdentityFn {
    <T>(arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn = identity;

我们可能想把泛型参数当作整个接口的一个参数。 这样我们就能清楚的知道使用的具体是哪个泛型类型。

interface GenericIdentityFn<T> {
    (arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

泛型类
我们还可以给类指定泛型

class MyClass<T>{
    x:T;
    y:T;
    show(x:T):T{

        return x;
    }
}

let mcls=new MyClass<number>();
let mcls1=new MyClass<string>();
mcls.show(1);
mcls1.show("yzq")

泛型约束
我们可以通过extends给泛型添加约束,添加约束的泛型传参的时候必须要符合约束的定义

interface lenWise {
    length: number;
}
// function loggingIdentity<T>(arg: T): T {
//     console.log(arg.length);  // 错误,不能调用length属性
//     return arg;
// }
function loggingIdentity<T extends lenWise>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

// loggingIdentity(3);//错误,添加了泛型约束,传进去的值必须要符合接口定义
loggingIdentity({length:1,name:"yzq"});

泛型约束泛型
所谓泛型约束泛型,就是我们通过extends关键字来实现一个类型被另一个类型锁约束。
比如,现在我们有两个对象,并把一个对象的属性拷贝到另一个对象。 我们要确保没有不小心地把额外的属性从源对象拷贝到目标对象,因此我们需要在这两个类型之间使用约束。

function copyFields<T extends U, U>(target: T, source: U): T {
    for (let id in source) {
        target[id] = source[id];
    }
    return target;
}

let x = { a: 1, b: 2, c: 3, d: 4 };

copyFields(x, { b: 10, d: 20 }); // okay
copyFields(x, { Q: 90 });  // error: property 'Q' isn't declared in 'x'.

在泛型中使用类类型

function create<T>(c: {new(): T; }): T {
    return new c();
}

总结:总体来说,TypeScript中泛型的使用方法跟java类似,只需要把平时常用的记住就行了。其他特殊的感觉暂时没有太大意义。

下一篇:

Angular环境搭建


如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喻志强(Xeon)

码字不易,鼓励随意。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值