TypeScript 中泛型的理解?应用场景?

一、是什么
泛型程序设计(generic programming)是程序设计语言的一种风格或范式
泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 在typescript中,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性
假设我们用一个函数,它可接受一个 number 参数并返回一个number 参数,如下写法:
function returnItem (para: number): number {
return para
}
如果我们打算接受一个 string 类型,然后再返回 string类型,则如下写法:
function returnItem (para: string): string {
return para
}
上述两种编写方式,存在一个最明显的问题在于,代码重复度比较高
虽然可以使用 any类型去替代,但这也并不是很好的方案,因为我们的目的是接收什么类型的参数返回什么类型的参数,即在运行时传入参数我们才能确定类型
这种情况就可以使用泛型,如下所示:
function returnItem<T>(para: T): T {
return para
}
可以看到,泛型给予开发者创造灵活、可重用代码的能力
二、使用方式
泛型通过<>的形式进行表述,可以声明:
函数
接口
类
函数声明
声明函数的形式如下:
function returnItem<T>(para: T): T {
return para
}
定义泛型的时候,可以一次定义「多个类型参数」,比如我们可以同时定义泛型 T 和 泛型 U:
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
swap([7, 'seven']); // ['seven', 7]
接口声明
声明接口的形式如下:
interface ReturnItemFn<T> {
(para: T): T
}
那么当我们想传入一个number作为参数的时候,就可以这样声明函数:
const returnItem: ReturnItemFn<number> = para => para
类声明
使用泛型声明类的时候,既可以作用于类本身,也可以作用于类的成员函数
下面简单实现一个元素同类型的栈结构,如下所示:
class Stack<T> {
private arr: T[] = []
public push(item: T) {
this.arr.push(item)
}
public pop() {
this.arr.pop()
}
}
使用方式如下:
const stack = new Stacn<number>()
如果上述只能传递 string 和 number 类型,这时候就可以使用 <T extends xx> 的方式猜实现「约束泛型」,如下所示:

除了上述的形式,泛型更高级的使用如下:
例如要设计一个函数,这个函数接受两个参数,一个参数为对象,另一个参数为对象上的属性,我们通过这两个参数返回这个属性的值
这时候就设计到泛型的索引类型和约束类型共同实现
索引类型、约束类型
索引类型 keyof T 把传入的对象的属性类型取出生成一个联合类型,这里的泛型 U 被约束在这个联合类型中,如下所示:
function getValue<T extends object, U extends keyof T>(obj: T, key: U) {
return obj[key] // ok
}
上述为什么需要使用泛型约束,而不是直接定义第一个参数为 object类型,是因为默认情况 object 指的是{},而我们接收的对象是各种各样的,一个泛型来表示传入的对象类型,比如 T extends object
使用如下图所示:

多类型约束
例如如下需要实现两个接口的类型约束:
interface FirstInterface {
doSomething(): number
}
interface SecondInterface {
doSomethingElse(): string
}
可以创建一个接口继承上述两个接口,如下:
interface ChildInterface extends FirstInterface, SecondInterface {
}
正确使用如下:
class Demo<T extends ChildInterface> {
private genericProperty: T
constructor(genericProperty: T) {
this.genericProperty = genericProperty
}
useT() {
this.genericProperty.doSomething()
this.genericProperty.doSomethingElse()
}
}
通过泛型约束就可以达到多类型约束的目的
三、应用场景
通过上面初步的了解,后述在编写 typescript 的时候,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性的时候,这种情况下就可以使用泛型
灵活的使用泛型定义类型,是掌握typescript 必经之路
TypeScript 中泛型的理解?应用场景?的更多相关文章
- Typescript中一些不理解的概念解释(泛型、断言、解构、枚举)
新的项目想使用typescript,因此又对其概念及使用过一遍,本文主要记录下对之前一些概念不太理解的地方. 1.泛型 定义: 在定义函数.接口或者类的时候,不预先指定具体的类型,而是在使用的时候再指 ...
- Java中泛型的理解
Java中的泛型,本质上来说,就是是参数化类型,就是说所操作的数据类型被指定为一个参数,而不是确定的某种类型.这种数据类型可以用在类.接口和方法创建中.即泛型类.泛型接口.泛型方法.这样说可能不够生动 ...
- TypeScript 中函数的理解?与 JavaScript 函数的区别?
一.是什么 函数是JavaScript 应用程序的基础,帮助我们实现抽象层.模拟类.信息隐藏和模块 在TypeScript 里,虽然已经支持类.命名空间和模块,但函数仍然是主要定义行为的方式,Type ...
- 十分钟教你理解TypeScript中的泛型
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://blog.bitsrc.io/understanding-generics-in-t ...
- Java 泛型 <? super T> 中 super 怎么 理解?与 < ? extends T>有何不同?
Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同? 简介 前两篇文章介绍了泛型的基本用法.类型擦除以及泛型数组.在泛型的使用中,还有个重要的 ...
- typescript 中的 infer 关键字的理解
infer 这个关键字,整理记录一下,避免后面忘记了.有点难以理解呢. infer infer 是在 typescript 2.8中新增的关键字. infer 可以在 extends 条件类型的字句中 ...
- TypeScript 中命名空间与模块的理解?区别?
一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...
- TypeScript Generics(泛型)
软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用.支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性. 在C#和 ...
- 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。
[TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...
- TypeScript 中的方法重载
方法重载(overload)在传统的静态类型语言中是很常见的.JavaScript 作为动态语言, 是没有重载这一说的.一是它的参数没有类型的区分,二是对参数个数也没有检查.虽然语言层面无法自动进行重 ...
随机推荐
- TLS原理与实践(四)国密TLS
主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 TLS作为保证网络通信安全的关键技术和基石被广泛应用,但目前主流 ...
- 6 定时器 &中断管理&资源管理
生成函数 周期,多久触发一次定时器(从定时器启动开始计算) 触发什么呢? 回调函数被调用,被谁调用呢 1,tick中断去调用timer函数 Linux中使用这个 (定时器回调函数若执行时间过长, ...
- mockjs 前端写完 给后台调 mock.js | 改到2.0版本
需求:最近活太忙了,实在是联调没有时间了,无奈又拾起来mockjs 1 安装mockjs npm install mockjs // 这是个只在开发的时候用,打包后就没有了,业务更安全 npm ins ...
- translate speaker 翻译朗读者API - vscode 插件推荐 单词发音
translate speaker 翻译朗读者API - vscode 插件推荐 单词发音 有个小bug,就是发音发两次,改个配置就好了. "translateSpeaker.mode&qu ...
- git 修改大小写远程分支失败
先说原因: windows大小写不敏感导致 最近由于项目需求,改回了windows开发环境,之前一直是 mac 开发环境,结果在windows环境下使用 git 时, 把某个之前大写的文件夹名称改 ...
- eclipse错误之Errors occurred during the build. Errors running builder 'JavaScript Validator' on project
把JavaScript Validator去掉.去掉的方法是:选择一个项目--右键Properties--Builders(排第二)--点一下右侧会有四项--取消第一项"JavaScript ...
- 【atcoder 293 E - Sugoroku 4】【动态规划,递推】
import java.io.IOException; import java.util.Arrays; import java.util.Scanner; public class Main { s ...
- ProtoBuf-gRPC实践
目录介绍 01.gRPC学习背景 1.1 为什么要学RPC 1.2 RPC是什么 1.3 网络库收益分析 1.4 学习计划说明 1.5 学习问题思考 02.ProtoBuf的介绍 2.1 ProtoB ...
- c# WPF制作百度网盘资源搜索工具
界面如下 1.搜索中 2.搜索成功 源码地址:https://github.com/BruceQiu1996/BaiduDiskSearcher 希望有用的学到的或者对此感兴趣的可以给一个star,谢 ...
- ArcMap的mxd文件没有数据、显示感叹号怎么办?
本文介绍在ArcMap软件中,导入.mxd地图文档文件后图层出现感叹号.地图显示空白等情况的解决办法. 在ArcMap软件使用过程中,我们经常会需要将包含有多个图层的.mxd地图文档文件导入软 ...