【Typescript 系列】第十节:泛型

144 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

1. 引言

什么是泛型?泛型有什么作用?在什么场景使用它呢? 今天我们来介绍下泛型,这个是类型系统中一个重要知识点。 我们引用下官方Ts文档介绍:

软件工程中,我们不仅要创建一致的定义良好的 API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。  

在像 C# 和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

2. 含义

首先,我们先来了解下官方变量名词:

T:(Type)官方泛型变量名词,表示任何类型(也就是我们常说的泛型)
K:Key)官方键值变量名词,表示对象中的类型
V:(Value)官方值变量名词,表示对象中的值的类型
E:(Element)表示元素类型

模板例句: function identity <T>(value: T) : T { return value } 解析如上:第一个泛型变量通过链式传递给参数类型(第二个T)和返回值类型(第三个T)

在使用上我们可以使用两种方式

  1. 直接定义要使用的类型
  2. Ts类型推断,自动帮我们推断类型

3. 作用

泛型简单来说就是对类型编程,当需要使用到的场景值,以及返回值是灵活多变的时候就可以使用泛型定义,它就像是一个占位符(当然在这里我们并不考虑使用any类型,因为总所周知any类型是类型系统的“万精油”,“漏洞”,专门用来逃避类型检测的,且不说写 any 类型不好,毕竟在 TS 中尽量不要写 any。),这样减少当一些场景重复定义大致相同类型,减少代码体量 请看例子一。

在类型定义使用过程中我们还可以给泛型加默认参数(请看例子二) 它有个重要方法:泛型方法定义约束(请看例子四)

4. 例子

例子一:避免因为不确定的行参类型重复的定义函数接收就想下面这样

function printFun(lineVal:string):string {
    return lineVal
}
function printFun(lineVal:string | number):string | number {
    return lineVal
}
// 或者直接使用这样暴力的方式,直接使用any
function printFun(lineVal:any):any {
    return lineVal
}
// 使用泛型一步搞定,T可以是调用时传入的任意形参,这样就做到了输入和输出的类型统一,且可以输入输出任何类型。
function print<T>(arg:T):T {
    return arg
}

例子二:

interface Iprint<T = number> {
    (arg: T): T
}

function print<T>(arg:T) {
    return arg
}

const myPrint: Iprint = print

例子三:

function tupleFun<T, U>(tuple: [T, U]): [U, T]{
    return [tuple[1], tuple[0]]
}

例子四:

interface Getlength {
    length: number
}

function printLength<T extends Getlength>(arg: T): T {
    return arg
}
const str = printLength('lin')
const arr = printLength([1,2,3])
const obj = printLength({ length: 10 })

5. 总结

一。泛型的使用,是为了可以在定义函数、接口或类的时候,不预先指定具体类型,而是在使用的时候再指定类型。减少重复定义代码,支持多种类型,提高扩展性,不必通过例子一中亢长的联合类型来定义,就像一个占位符、或者说一个变量,在使用的时候可以把定义的类型像参数一样传入,它可以原封不动地输出。 二。泛型在:函数形参参数、函数返回值、类的实例成员、类的方法等提供了约束的方式。