• TypeScript中的泛型使用详解


    一、泛型的概述

    "泛"就是广泛的意思,"型"就是数据类型。顾名思义,泛型就是适用于多种数据类型的一种类型。

    它能够帮助我们构建出复用性更强的代码。

    假如有如下函数:

    function sum(num: number): number {
      return num
    }
    
    • 1
    • 2
    • 3

    此时函数的参数和返回值都必须是number类型的。

    但是其它类型的数据,比如stringboolean或者自定义的Teacher等类型就没有办法使用这个函数。

    虽然any可以解决这个问题,但是函数参数和返回值定义为any的时候,具体的类型信息就已经丢失了。

    比如传入的是一个number,那么我们希望返回的并不是any类型,而是number类型。

    所以,我们需要在函数中可以捕获到参数的类型是number,并且同时使用它来作为返回值的类型。

    因此需要在这里使用一种特性的变量 - 类型变量(type variable),它作用于类型,而不是值!

    二、泛型的基本使用

    2.1 泛型函数示例

    在定义一个函数时,不决定这些参数的类型,而是让调用者以参数的形式告知函数参数应该是什么类型。

    function sum<T>(num: T): T {
      return num
    }
    
    • 1
    • 2
    • 3

    我们可以把Type看做额外的一个参数,把类型参数化。

    它可以做到, 在定义这个函数时, 不决定这些参数的类型, 而是让调用者以参数的形式告知, 这里的函数参数应该是什么类型。

    2.2 传入泛型的方式

    函数定义时,<>的位置就是之后泛型的传入位置,比如上面函数的

    传入泛型时,只要把具体的泛型传递给即可。

    这样函数定义时的,函数参数,和函数返回值的T类型,都会变成传入的具体参数类型。

    1)通过 <类型> 的方式将泛型传递给函数
    sum<number>(100) 						// 声明sum函数的泛型为number类型,并传递number类型的参数
    sum<{name: string}>({ name: "zs" }) 	// 声明sum函数的泛型为{name: string}类型
    sum<number[]>([15, 25]) 				// 声明sum函数的泛型为number类型的数组
    
    • 1
    • 2
    • 3
    2)通过类型推导,自动推到出我们传入变量的类型

    在这里会推导出它们是 字面量类型的,因为字面量类型对于我们的函数也是适用的

    sum(100)
    sum("test")
    
    • 1
    • 2

    三、常用的泛型名称

    开发中可能会看到一些常用的名称,不同的名称会有不同语义化意义。

    • TType的缩写,类型

    • K、Vkeyvalue的缩写,键值对

    • EElement的缩写,元素

    • OObject的缩写,对象

    四、传入多个泛型

    function fun<T, E>(arg1: T, arg2: E) {
      console.log(arg1, arg2)
    }
    
    fun<number, string>(100, "test")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当一个函数有多个泛型时,可以用不同的泛型名称来标识。

    上面的fun函数的参数一的类型由泛型T决定,而参数二由泛型E决定。

    五、泛型接口

    在定义接口的时候也可以使用泛型来对接口内的成员进行类型约束。

    2.1 泛型接口的基本使用

    interface IInfo<T1, T2> {
      name: T1
      age: T2
    }
    
    const info: IInfo<string, number> = {
      name: "zs",
      age: 25
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2 泛型接口中的基本使用

    泛型接口是没有类型推导的, 但是可以有泛型默认值。

    // 泛型接口定义默认类型
    interface IPerson<T1 = string, T2 = number> {
      name: T1
      age: T2
    }
    
    const p: IPerson = {
      name: "chenyq",
      age: 123
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    六、泛型类的使用

    class Point<T> {
      x: T
      y: T
      z: T
    
      constructor(x: T, y: T, z: T) {
        this.x = x
        this.y = y
        this.z = y
      }
    }
    
    // 泛型类自动推导类型
    const point1 = new Point("1.33.2", "2.22.3", "4.22.1")
    // 泛型类明确泛型类型
    const point2 = new Point<string>("1.33.2", "2.22.3", "4.22.1")
    const point3: Point<string> = new Point("1.33.2", "2.22.3", "4.22.1")
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    数组泛型的写法:

    // 定义字符串数组
    const arr1: string[] = ["a", "b", "c"]			
    const arr2: Array<string> = ["a", "b", "c"]
    
    • 1
    • 2
    • 3

    七、泛型约束

    有时候希望传入的类型具有某些共性,但是这些共性可能不是在同一种类型中。

    比如stringarray都是有length的,或者某些对象也是会有length属性的。

    那么只要是拥有length的属性都可以作为我们的参数类型。

    interface ILength {
      length: number
    }
    
    // 泛型继承接口, 这样传入的泛型类型就必须和ILength接口一样具有length属性才可以
    function getLength<T extends ILength>(arg: T) {
      console.log(arg.length)
    }
    
    // getLength(123) 			// 123没有length无法传入
    getLength("abcdefg") 		// 7
    getLength([10, 20, 30, 40]) // 4
    getLength({ length: 20 })	// 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    T extends表示传入的类型必须是extends后面的类型或者子类型。

  • 相关阅读:
    TS编译选项——编译TS文件同时对JS文件进行编译
    一个tomcat中部署的多个war,相当于几个jvm
    c++ 小案例:判断质数&&猜数字&&用符号填补心形图案
    arcgis中编码方式改变引起的shp文件乱码、字符截断问题处理
    lnmp平台部署web应用,安装Discuz社区平台详细文章——更新中
    超声波气象站无需架设通讯线路,传输距离远,传输效率高
    Mysql数据库SQL语句与管理
    Material Design之CoordinatorLayout 与AppbarLayout与CollapsingToolbarLayout
    【Java】springboot 页面不显示 throw 的错误提示信息
    爬虫过程和反爬
  • 原文地址:https://blog.csdn.net/qq_44749491/article/details/127545292