前言

本文主要记录下 TypeScript 泛型知识点,日常学习总结篇。

一、概念

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

二、例子

首先来看一个简单的例子,体会一下泛型可解决的问题。

需求:定义一个 identity 函数,这个函数会返回任何传入它的值。如传入参数的类型是 number,函数返回类型为 number。

function identity(arg: number): number {return arg;
}

然后,需求变更,传入参数类型可以是 string,函数返回类型也是 string。

此时可以使用联合类型实现需求,代码如下。

function identity(arg: number | string): number | string {return arg;
}

然后需求再次变更,传入的参数类型可以支持更多类型,甚至任何类型时,如何实现呢?

此时可以使用 any 类型来定义函数,代码如下。

function identity(arg: any): any {return arg;
}

使用 any 类型会导致这个函数可以接收任何类型的 arg 参数,但是这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。

例如传入一个 number 类型的参数,使用 string 类型来接收函数的返回值,此时 TS 并不会报错提示我们。代码如下。

const value: string = identity(89)

这时候,泛型就派上用场了。代码如下。

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

这样就可以做到函数传入的类型与返回的类型一致,而且可以传入返回任何类型。

如果类型不一致,TS 就会报错。

三、泛型基本使用

泛型的语法是 <> 里写类型参数,一般可以用 T 来表示。T 表示 Type,实际上 T 可以用任何有效的名称代替。除了 T 之外,常见的泛型变量还有 K、V 和 E 等。

  • K(key):表示对象中的键类型;
  • V(value):表示对象中的值类型;
  • E(element):表示元素类型。

泛型中的 T 被称为泛型变量,或者说一个类型占位符。就像传递参数一样,在使用的时候把指定的实际类型,链式传递给参数类型和返回值类型。

在使用的时候,可以有两种方式指定类型:

  • 定义具体类型;
  • TS 类型推断,自动推导出类型。
identity<string>('abc') // 定义具体类型identity(123) // TS 类型推断,自动推导出类型

四、处理多个泛型参数

需求:定义一个函数,传入一个只有两项的元组类型数据,交换元组的值的顺序,返回这个元组。

实现代码如下:

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

传入一个参数,定义元组第 0 项为 string 类型,第 1 项为 number 类型。

const arr = swap<string, number>(['abc', 123])

得到的函数返回值,第 0 项为 number 类型,第 1 项为 string 类型。

第 0 项上全是 number 类型的方法,如下图所示。

第 1 项上全是 string 类型的方法,如下图所示。

五、泛型接口

定义接口时, 为接口中的属性或方法定义泛型类型,在使用接口时, 再指定具体的泛型类型。

interface ICreateObj<K, V> {name: K,age: V
}const obj: ICreateObj<string, number> = {name: 'jenny',age: 18
}

六、泛型类

在类中使用泛型也很简单,只需要在类名后面,使用 <T, ...> 的语法定义任意多个类型变量。

class GenericFn<T> {defaultValue: T;add: (a: T, b: T) => T
}// 传入 number 类型
const genericNumber = new GenericFn<number>()
genericNumber.defaultValue = 6
genericNumber.add = (x, y) => x + y
genericNumber.add(genericNumber.defaultValue, 8)  // 14// 传入 string 类型
const genericString = new GenericFn<string>()
genericString.defaultValue = 'a'
genericString.add = (a, b) => a + b
genericString.add(genericString.defaultValue, 'c') // ac

七、默认参数

在 TypeScript 2.3 以后,我们可以为泛型中的类型参数指定默认类型。当使用泛型时没有在代码中直接指定类型参数,从实际值参数中也无法推断出类型时,这个默认类型就会起作用。

泛型参数默认类型与普通函数默认值类似,对应的语法很简单,即 <T=Default Type>,对应的使用示例如下:

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

八、泛型约束

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法。

需求:实现一个函数,打印出传入参数的长度。

可以这样实现:

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

上例中,泛型 T 不一定包含属性 length,所以编译的时候 TS 会提示错误,类型 T 上不存在属性 length。如下图:

这时,就可以对泛型进行约束,只允许这个函数传入那些包含 length 属性的变量。

interface ILength {length: number
}function getLength<T extends ILength>(arg: T): T {console.log(arg.length)return arg
}

上面代码中,最关键的就是 <T extends ILength>,让泛型 T 继承接口 ILength,也就是传入的参数类型必须包含 length 属性,这样就能约束泛型。

此时再次调用 getLength 函数的时候,传入的参数 arg 如果不包含 length 属性,那么在编译阶段 TS 就会报错。如下图所示。

此外,还可以使用 , 号来分隔多种约束类型,比如:<T extends Type1, Type2, Type3>

TypeScript - 泛型相关推荐

  1. 泛型 typescript_如何把你的头围绕Typescript泛型

    泛型 typescript by Nadeesha Cabral 通过Nadeesha Cabral 如何把你的头围绕Typescript泛型 (How to wrap your head aroun ...

  2. TypeScript泛型约束

    泛型约束 有了泛型之后,一个函数或容器类能处理的类型一下子扩到了无限大,似乎有点失控的感觉.所以这里又产生了一个约束的概念.我们可以声明对类型参数进行约束. 我们还拿上文中的student栗子来说,想 ...

  3. TypeScript泛型详解

    泛型 泛型(Generics)是指在定义函数.接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性. 示例 我们先实现一个student方法获取不同属性来看看使用: JavaScr ...

  4. TypeScript泛型工具

    Required 将类型的属性变成必选 interface Person {name?: stringage?: numberhobby?: string[] }// 下面的类型不用定义, TypeS ...

  5. TypeScript 泛型T使用整理

    一.介绍 相C#和Java等以上,TypeScript可以使用泛型来创建可重用的组件.支持当前数据类型,同时也能支持未来的数据类型.扩展灵活. 二.泛型的定义.使用 使用泛型可以创建泛型函数.泛型接口 ...

  6. 【TS】1368- 秒懂 TypeScript 泛型工具类型!

    阿宝哥精心准备的<轻松学 TypeScript> 视频教程已经更新到第十九期了,合集播放量已达 14W+.通过形象生动的动画,让你轻松搞懂 TypeScript 的难点和核心知识点! 如果 ...

  7. TypeScript 泛型

    TS里面有泛型让我很意外,这个比AS3确实要强大: let myIdentity_change : <T>(arg:T)=>T=function(a){ return a };con ...

  8. TypeScript泛型

    泛型的概念 指不预先确定的数据类型,具体的类型要在使用的时候才能确定.咋一听,是不是觉得JavaScript本身就是这样?这是由于理解有误.前面说"在使用的时候确定",而非在程序执 ...

  9. Typescript泛型与implements子句

    一.泛型的基本使用 与extends的区别 泛型可以理解为宽泛的类型,通常用于类和函数.使用的时候我们再指定类型 泛型不仅可以让我们的代码变得克加健壮,还能让我们的代;码在变得键壮的r时保持灵活性和可 ...

最新文章

  1. oracle 与 client端执行结果不一致_不同模式下Spark应用的执行过程
  2. 小程序制作五星点评(默认五星)
  3. python判断几个数最大最小_python 找出list中最大或者最小几个数的索引方法
  4. JAVA Spring 事物 ( 已转账为例 ) 基于 AOP 注解
  5. 云服务器php版本修改,云服务器 更改php版本
  6. git提交到github总是要输入密码_GitHub不为人知的秘密
  7. libsvm在matlab中使用的常见错误及libsvm的使用
  8. Chrome浏览器V43版本不支持silverlight 5.0的解决办法
  9. IAT 注入ImportInject(dll)
  10. Ubuntu下利用python实现自动打卡系统全过程
  11. Android 截屏监听分享
  12. CPU飙高原因及解决方案
  13. Android Killer反编译时遇到的异常
  14. Git超详解七 储藏 (看不懂算我输)
  15. XILINX XC7A200T-1FBG676C FPGA - 现场可编程门阵列
  16. 检测特殊字符的正则表达式
  17. Java读取word模板,并动态生成word
  18. infer.net 入门2 用一个侦探故事来讲解,通俗易懂
  19. 【分享】许多 有意思的 颜文字表情包
  20. 金博医药WMS仓储管理系统的功能特点

热门文章

  1. req.on 和req.body的使用
  2. 一次维修打印机复印件的记录
  3. excel函数公式加减乘除
  4. 【IoT】寻光智能车与循迹智能车
  5. SpringBoot中 判断上传的文件类型 MultipartFile file
  6. python正则表达式匹配网址中的域名_正则表达式匹配域名、网址、url
  7. 导入cx_Oracle时提示DLL load failed问题解决
  8. 互联网应届毕业生简历心得
  9. matlab %4.3f,MATLAB程序设计教程(4)—MATLAB文件操作
  10. 基调网络提供网页首屏监测技术 助力互联网应用企业提升网站性能