zoukankan      html  css  js  c++  java
  • 深入理解TypeScript——文档篇之泛型

    一、介绍

    类型变量,它是一种特殊的变量,只用于表示类型而不是值。

    function identity<T>(arg: T): T { // 声明带有泛型的函数
        return arg;
    }
    

    二、使用

    1. 传入所有的参数,包含类型参数:

      let output = identity<string>("myString");  // type of output will be 'string'
      
    2. 类型推论

      let output = identity("myString");  // type of output will be 'string'
      

      编译器可以查看myString的值,然后把T设置为它的类型。 类型推论帮助我们保持代码精简和高可读性。如果编译器不能够自动地推断出类型的话,只能像上面那样明确的传入T的类型,在一些复杂的情况下,这是可能出现的。

    三、类型

    1. 类型参数在最前面。

      function identity<T>(arg: T): T {
          return arg;
      }
      
      let myIdentity: <T>(arg: T) => T = identity;
      
    2. 可以使用不同的泛型参数名。

      function identity<T>(arg: T): T {
          return arg;
      }
      
      let myIdentity: <U>(arg: U) => U = identity;
      
    3. 使用带有调用签名的对象字面量来定义。

      function identity<T>(arg: T): T {
          return arg;
      }
      
      let myIdentity: {<T>(arg: T): T} = identity;
      
      interface GenericIdentityFn {
          <T>(arg: T): T;
      }
      
      function identity<T>(arg: T): T {
          return arg;
      }
      
      let myIdentity: GenericIdentityFn = identity;
      
    4. 泛型接口参数。

      // 把参数放在调用签名里
      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; // 锁定了之后代码里使用的类型
      

      除了泛型接口,我们还可以创建泛型类。
      注意,无法创建泛型枚举和泛型命名空间。

    四、泛型类

    泛型类使用( <>)括起泛型类型,跟在类名后面。
    ```ts
    class GenericNumber<T> {
        zeroValue: T;
        add: (x: T, y: T) => T;
    }
    
    let myGenericNumber = new GenericNumber<number>();
    myGenericNumber.zeroValue = 0;
    myGenericNumber.add = function(x, y) { return x + y; };
    ```  
    

    注意:泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。
    这里意思是泛型类约束的是除类静态部分其他的属性部分。

    五、泛型约束

    1. 限制传入参数的类型。

      interface Lengthwise { // 创建一个包含 .length属性的接口
          length: number;
      }
      
      function loggingIdentity<T extends Lengthwise>(arg: T): T { // 使用这个接口和extends关键字来实现约束
          console.log(arg.length);  // Now we know it has a .length property, so no more error
          return arg;
      }
      
    2. 在泛型约束中使用类型参数
      两个类型之间使用约束

      function getProperty(obj: T, key: K) {
          return obj[key];
      }
      
      let x = { a: 1, b: 2, c: 3, d: 4 };
      
      getProperty(x, "a"); // okay
      getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
      
    3. 在泛型里使用类类型
      (1) 工厂函数

      function create<T>(c: {new(): T; }): T {
          return new c();
      }
      
      // test
      class Test {
          name: string = 'test';
      }
      
      let a = create(Test)
      
      console.log(a, 123);
      

      (2) 原型属性推断并约束构造函数与类实例的关系

      class BeeKeeper {
        hasMask: boolean = false;
      }
      
      class ZooKeeper {
          nametag: string = '333';
      }
      
      class Animal {
          numLegs: number = 1;
      }
      
      class Bee extends Animal {
          keeper: BeeKeeper = new BeeKeeper();
      }
      
      class Lion extends Animal {
          keeper: ZooKeeper = new ZooKeeper();
      }
      
      function createInstance<A extends Animal>(c: new () => A): A {
          return new c();
      }
      
      var a = createInstance(Lion).keeper.nametag;  // typechecks!
      // createInstance(Bee).keeper.hasMask;   // typechecks!
      
      console.log(a, 123);
      
      function create<T>(c: {new(): T; }): T {
        return new c();
      }
      
  • 相关阅读:
    找到一种给vs2012对话框插入背景图片不会失真的方法
    第一次用C语言把数据写入文件中
    Java学习路线图
    一:MyBatis Generator 【SpringMvc+Spring+MyBatis+Maven整合学习笔记】
    windows系统安装Redis
    js子级窗口相互调用父级的方法
    MSSQL 发布订阅,实现读写分离
    查看MS SQL最耗时间资源的SQL
    数据库优化
    mybatis与hibernate区别
  • 原文地址:https://www.cnblogs.com/hackftz/p/13811796.html
Copyright © 2011-2022 走看看