Typescript 泛型

  1. Typescript 泛型
  2. 基本使用
  3. 在泛型里使用类类型
  4. 泛型函数接口
  5. 泛型类
  6. 泛型约束

Typescript 泛型

当我们的参数是一个不确定的数据类型的时候,且返回值和传入的参数是同一种数据类型,我们就可以使用泛型,我们也可以使用any,但是any不能确保输入和输出是同一种数据类型,会丢失一些信息

基本使用

下面是一个最简单的泛型例子,T可以是任何名字,可以当它是一个变量。

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

使用的时候,指定具体的泛型变量类型,即可保证输出也是string类型

let output = identity<string>('hello')
console.log(output)

我们不需要手动指定泛型的变量类型,ts会帮我们自动检测传过去的是什么类型

let output1 = identity('world')
console.log(output1);

使用泛型变量,下面的代码会报错,因为arg指定类型是T,但是T是泛型,不确定传进来的是很么类型,如果是数字就没有length属性,因此会报错

function getLength<T>(arg: T): T {
  console.log(arg.length);
  return arg
}

使用<T>指定了泛型,传入的参数规定为泛型组成的数组,返回值也是一样,就可以使用了

function getLength1<T>(arg: T[]): T[] {
  console.log(arg.length);
  return arg
}

// 这种方式也可以
function getLength2<T>(arg: Array<T>): Array<T> {
  console.log(arg.length);
  return arg
}

箭头函数形式

const getLength3 = <U>(arg: Array<U>): Array<U> => { return arg }

let len = getLength3([1, '2', true])
console.log(len);

在泛型里使用类类型

以下代码函数create接收一个名为C的类,返回C的实例,如果不是传入的类,代码将会报错

function create(C) { 
  return new C()
}

使用泛型队该函数进行约束,参数c后面{new ()} 表示c是一个类,可以new,再加上一个传入类型和返回类型,就可以这么写

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

泛型函数接口

定义泛型函数接口,可以有以下两种形式

  1. 泛型定义在函数中,这种写法的特点是用户调用的时候,可以给定任意数据类型
    interface ConfigFn {
      <T>(value: T): T;
    }
    
    function getData<T>(value: T): T {
      console.log(value);
      return value
    }
    
    const myGetData: ConfigFn = getData
    // 函数实现
    myGetData<string>('baihuzi.com')
    myGetData<number>(10086)
    
  2. 泛型定义在接口中,推荐这种写法,这种方式提前指定泛型的数据类型
    interface ConfigFn1<T> {
      (value1: T): T;  // 泛型接口
    }
    
    // 函数实现,箭头函数写法
    // 提前执行函数需要的数据类型,这里使用的时候只能传字符串类型的数据
    const myGetData1: ConfigFn1<string> = value1 => {
      console.log(value1);
      return value1
    }
    myGetData1('www.baihuzi.com')
    // myGetData1(123)   // error
    

泛型类

泛型类使用<>括起泛型类型,跟在类名后面。

class GenericNumber<T> {
  zeroValue: T;
  constructor(value: T){
    this.zeroValue = value
  }
  show():T {
    return this.zeroValue
  }
}


let myGenericNumber = new GenericNumber<number>(123);  
myGenericNumber.zeroValue = 0;
myGenericNumber.show()

let stringNumeric = new GenericNumber<string>('string');
stringNumeric.zeroValue = "";
myGenericNumber.show()

泛型约束

泛型约束规定泛型必须要有哪些属性,使用extends关键字进行定义,理解起来就是泛型T继承自BoxConf,因此泛型T上必须要有sizelength属性,我们在传参的时候就需要带上这些属性

interface BoxConf {
  size: string
  length: number
}

// 泛型约束,必须要包含JJ中的属性
function createHuman<T extends BoxConf>(what: T): T {
  return what
}

createHuman({
  name: 'Jack',
  age: 18,
  size: 'large',  // 缺少这个会报错
  length: 18  // 缺少这个也会报错
})

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com