【TypeScript】简单介绍一下泛型

315 阅读3分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战


泛型简单介绍

真的只是简单介绍,泛型东西可太多、太难了

(1)概念

  • 泛型:

    • 它是在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性

      泛型,顾名思义,即泛指一类类型,在定义时,我们不知道它会接收什么样的类型,会返回什么样的类型

      因此,我们用泛型来代替一个具体的类型,相当于一个类型占位符

      然后,在使用时才将具体的类型传给我们的定义

(2)使用

  • 泛型变量

    • 在定义时,需要在方法名后面添加尖括号<>,表示支持一个泛型参数

      • 如:<T>,这个T可以是任意指定的

      一般情况下,常用的泛型变量可以用这些字母来表示(可以任意指定)

      • T(Type):表示一个 TypeScript 类型
      • K(Key):表示对象中的键类型
      • V(Value):表示对象中的值类型
      • E(Element):表示元素类型
    • 在使用时,需要将一个具体的类型作为参数传入尖括号

      • 如:<Number>
  • 泛型函数:

    function myFunc1<T>(arg: T): T{
        return arg
    }
    myFunc1<string>('Ruovan') // Ruovan
    
    

    表示定义一个泛型函数,并将 一个类型 类似于作为参数 传递给这个函数 然后这个函数的 参数和返回值 都会是这个类型

    • 它表示的是一个泛指的类型,只有在具体使用这个函数时,才能确定这个类型是什么
    // 不仅仅可以传入一个泛型变量,还可以传入多个
    function myFunc2<T, X>(arg1: T, arg2: X): T{
        return arg1 + arg2
    }
    
    myFunc2<String, Number>('Ruovan', 24) // Ruovan24
    // 或者,可以省略尖括号,会自动做一个类型推断
    myFunc2('Ruovan', 24) // Ruovan24
    
    
    
  • 泛型接口

    • 在接口名后面添加尖括号
    • 然后对接口中的属性或者方法定义泛型
    // 定义一个泛型接口
    interface MyInterface<T> {
        // 表示参数 arg 的类型 与使用接口时 传进来的类型参数 保持一致
        arg1: T;
        arg2: T
    }
    
    
  • 泛型类

    • 在类名后定义传入的泛型
    • 然后对类的属性或方法定义泛型
    // 定义一个泛型类
    class MyClass<T, A> {
        arg1: T
        arg2: A
        constructor(value1: T, value2: A) {
            this.arg1 = value1
            this.arg2 = value2
        }
        add(): A {
            return this.arg1 + this.arg2
        }
    }
    
    let class = new MyClass<number, string>(24, 'Ruovan');
    
    class.add() / 24Ruovan
    
    

(3)泛型约束

  • 泛型约束

    某种程度上来看,泛型和any类似,但又不同

    • 对于any,你可以传任何类型,并且对你传入的类型的使用都是不会报错的
      • 即,比如你传入的是number类型,但使用的是string类型的方法,是无法达到类型检测的效果的
    • 对于泛型,你传入了什么类型,就只能使用这个类型的属性或者方法,如果没有,就会报错
      • 即,你传入的是number类型,就只能使用number类型的属性或者方法
    • 所以,在使用泛型时,如果我们想要使用的是具体的某种类型的方法,那么就要对泛型进行约束
    • 可以使用extends来扩展一个含有我们需要的属性或者方法的接口

      // 1. 先定义一个接口
      interface Len {
          length: number;
      }
      
      // 2. 然后让泛型继承这个接口,表示当前泛型是 由length属性 的一类类型
      function myFunc<T extends Len>(arg: T): T{
          console.log(arg.length)
          return arg
      }
      
      

      通过继承extends方式来对泛型进行约束,可以传入含有指定属性的类型

      对于其它类型,则会报错

      当然,也可以同时继承多个接口


本人前端小菜鸡,如有不对请谅解