7、TypeScript 使用泛型

376 阅读3分钟

一、函数中使用泛型

以一个简单的student方法,方法接受两个参数firstsecond,参数有可能是字符串类型,也有可能是数字类型。如下:

function student(first: string | number, second: string | number) {
    return `${first}${second}`;
  }
student("小明", "小红");

现在有这样一个需求,就是first参数如果传的是字符串类型,要求second也传字符串类型.同理,如果是number类型,就都是number类型。这时候就需要使用到泛型

1.初始泛型概念

泛型的定义使用<>(尖角号)进行定义的,比如现在给student方法一个泛型,名字就叫做T(可自定)。如下:

function student<T>(first:T, second: T) {
    return `${first}${second}`;
  }
student<string>("小明", "小红");
//student<number>(1, 2);

2.泛型在数组中使用

泛型在数组中使用,两种方法,第一种是直接使用[],第二种是使用Array<泛型>。 如下:

function teacher<T>(params: T[]) {
    return params;
  }
teacher<string>(["123", "456"]);
function teacher<T>(params: Array<T>) {
    return params;
  }
teacher<number>([1, 2]);

3.多个泛型的定义

一个函数是可以定义多个泛型的,如下:

function student<T, P>(first: T, second: P) {
    return `${first}${second}`;
  }
student < number, string > (1, "小明");

泛型在造轮子的时候经常使用,因为造轮子很多东西都需要灵活性。泛型给了我们很好的灵活性。需要注意的是,如果函数定义了多个泛型,使用时要对应的定义出具体的类型。

4.泛型的类型推断

泛型也是支持类型推断的,如下:

function student<T, P>(first: T, second: P) {
    return `${first}${second}`;
  }
student(1, "小明");

image.png 不建议大量使用类型推断,这会让代码易读性下降

二、类中使用泛型

先编写一个基本的类Teacher,在类的构造函数中(constructor)需要传递一组teacher的名称,然后再通过下边名称,代码如下:

class Teacher {
    constructor(private name: string[]) {}
    getGirl(index: number): string {
      return this.name[index];
    }
  }
  
const selectGirl = new Teacher(["张老师", "王老师", "李老师"]);
console.log(selectGirl.getGirl(1));

1、初始化泛型

class Teacher <T>{
    constructor(private name: T[]) {}
    getTecher(index: number): T {
      return this.name[index];
    }
  }
  
const teacher = new Teacher<string>(["张老师", "王老师", "李老师"]);
console.log(teacher.getTecher(1));

2、泛型中的继承

增加一个需求,要求返回是一个对象中的name,如下:

return this.name[index].name;

现在的代码一定时报错的,但是这时候还要求我们这么做,意思就是说传递过来的值必须是一个对象类型的,里边还要有name属性。这时候就要用到继承了,我用接口的方式来实现,然后用extends关键字实现泛型继承。如下:

interface TeacherN {
    name: string;
  }
class Teacher <T extends TeacherN>{
    constructor(private name: T[]) {}
    getTecher(index: number): string {
      return this.name[index].name;
    }
  }
  
const teacher = new Teacher([{name:'李老师'},{name:'王老师'},{name:'张老师'}]);
console.log(teacher.getTecher(1));

3、泛型约束

现在的泛型可以是任意类型,可以是对象、字符串、布尔、数字都是可以的。但你现在要求这个泛型必须是string或者number类型。还是可以使用关键字extends来进行约束,如下:

class Teacher <T extends number | string>{
    constructor(private name: T[]) {}
    getTecher(index: number): T {
      return this.name[index];
    }
  }
  
const teacher = new Teacher<string>(["张老师", "王老师", "李老师"]);
console.log(teacher.getTecher(1));

如果改为number和string以外的类型,就会出现报错。如下:

const teacher = new Teacher<boolean>([true,true,false]);

image.png

在实际工作中,泛型的应用更广泛和复杂。

学习日期:2022/1/5

视频参考www.bilibili.com/video/BV1qV…

文档参考jspang.com/detailed?id…

仅供个人学习和记录