• TypeScript学习笔记(六):泛型


    认识泛型

    TypeScript也实现了类型于C#和Java的泛型以实现类型的参数化,我们先看一个需求:

    1 function identity(arg: any): any {
    2     return arg;
    3 }

    我们希望方法identity可以传入任意类型,并且返回传入的类型,这样写可以达到效果但是不能确定返回的类型,使用泛型的写法如下:

    复制代码
    1 function identity<T>(arg: T): T {
    2     return arg;
    3 }
    4 
    5 var output = identity<string>("myString");  // type of output will be 'string'
    6 var output = identity("myString");  // type of output will be 'string'
    复制代码

    我们可以指定类型,也可以让编译器自动来识别类型。

    泛型数组

    我们也可以通过泛型来指定一个数组,写法如下:

    复制代码
    1 function loggingIdentity<T>(arg: T[]): T[] {
    2     console.log(arg.length);  // Array has a .length, so no more error
    3     return arg;
    4 }
    5 
    6 function loggingIdentity<T>(arg: Array<T>): Array<T> {
    7     console.log(arg.length);  // Array has a .length, so no more error
    8     return arg;
    9 }
    复制代码

    泛型类型

    我们可以指定一个带有泛型的函数:

    1 function identity<T>(arg: T): T {
    2     return arg;
    3 }
    4 
    5 var myIdentity: <U>(arg: U)=>U = identity;

    还有另一种写法:

    1 function identity<T>(arg: T): T {
    2     return arg;
    3 }
    4 
    5 var myIdentity: {<T>(arg: T): T} = identity;

    使用函数接口的写法如下:

    复制代码
    1 interface GenericIdentityFn {
    2     <T>(arg: T): T;
    3 }
    4 
    5 function identity<T>(arg: T): T {
    6     return arg;
    7 }
    8 
    9 var myIdentity: GenericIdentityFn = identity;
    复制代码

    同时泛型还可以作为类型的参数而不是方法的参数,写法如下:

    复制代码
    1 interface GenericIdentityFn<T> {
    2     (arg: T): T;
    3 }
    4 
    5 function identity<T>(arg: T): T {
    6     return arg;
    7 }
    8 
    9 var myIdentity: GenericIdentityFn<number> = identity;
    复制代码

    泛型类

    泛型除了可以用在接口上以外,当然还可以用在类上:

    复制代码
     1 class GenericNumber<T> {
     2     zeroValue: T;
     3     add: (x: T, y: T) => T;
     4 }
     5 
     6 var myGenericNumber = new GenericNumber<number>();
     7 myGenericNumber.zeroValue = 0;
     8 myGenericNumber.add = function(x, y) { return x + y; };
     9 
    10 var stringNumeric = new GenericNumber<string>();
    11 stringNumeric.zeroValue = "";
    12 stringNumeric.add = function(x, y) { return x + y; };
    13 alert(stringNumeric.add(stringNumeric.zeroValue, "test"));
    复制代码

    使用方法和C#与Java一致。

    泛型约束

    之前的泛型可以是任意的类型,我们还可以约束泛型的类型,我们先看一个会报错的例子:

    1 function loggingIdentity<T>(arg: T): T {
    2     console.log(arg.length);  // Error: T doesn't have .length
    3     return arg;
    4 }

    报错原因是,类型T没有length属性,我们可以为类型T指定一个类型,如下:

    复制代码
    1 interface Lengthwise {
    2     length: number;
    3 }
    4 
    5 function loggingIdentity<T extends Lengthwise>(arg: T): T {
    6     console.log(arg.length);  // Now we know it has a .length property, so no more error
    7     return arg;
    8 }
    复制代码

    写法是通过extends来指定类型T的类型必须是实现了Lengthwise接口的类型。

    调用如下:

    1 loggingIdentity(3);  // Error, number doesn't have a .length property
    2 loggingIdentity({length: 10, value: 3});  

    泛型约束泛型

    某些情况下,我们可能会有如下的需求:

    1 function find<T, U extends Findable<T>>(n: T, s: U) {   // errors because type parameter used in constraint
    2   // ...
    3 } 
    4 find (giraffe, myAnimals);

    这种写法会报错,可以使用下面正确的写法来达到效果:

    1 function find<T>(n: T, s: Findable<T>) {   
    2   // ...
    3 } 
    4 find(giraffe, myAnimals);

    在泛型中使用类类型

    有时我们希望可以指定泛型的构造函数和属性,写法如下:

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

    再看另外一个例子:

    复制代码
     1 class BeeKeeper {
     2     hasMask: boolean;
     3 }
     4 
     5 class ZooKeeper {
     6     nametag: string; 
     7 }
     8 
     9 class Animal {
    10     numLegs: number;
    11 }
    12 
    13 class Bee extends Animal {
    14     keeper: BeeKeeper;
    15 }
    16 
    17 class Lion extends Animal {
    18     keeper: ZooKeeper;
    19 }
    20 
    21 function findKeeper<A extends Animal, K> (a: {new(): A; 
    22     prototype: {keeper: K}}): K {
    23 
    24     return a.prototype.keeper;
    25 }
    26 
    27 findKeeper(Lion).nametag;  // typechecks!
    复制代码
  • 相关阅读:
    Decimal、 Float、 Double 使用
    jdk1.7的collections.sort(List list)排序问题
    $watch、$digest、$apply
    BeanNameViewResolver
    This system is not registered with RHN
    JNI字段描述符-Java Native Interface Field Descriptors
    服务器端cs文件
    ASP.NET基础(一)
    Android开发日记(七)
    登陆 注册
  • 原文地址:https://www.cnblogs.com/lancidie/p/7344918.html
Copyright © 2020-2023  润新知