TypeScript学习 | 泛型

简介

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

作用

可以保证类型安全的前提下,让函数、接口或类与多种类型一起工作,从而实现复用

基本使用

举个例子:

创建一个id函数、该函数传入什么数据就返回数据本身,也就是参数和返回值类型相同。

typescript 复制代码
function id(value:number): number {
  return value
}

id<number>(99) // 99
typescript 复制代码
function id(value:string): string {
  return value
}

id<string>('hhh') // hhh

综上所述、上面两个函数接收的类型是写死的,只能传入相应的数据类型,为了能让函数接口任意类型吗,可以将参数类型改为any。但是这样就失去TS的类型保护,类型不安全。

这时候,泛型就能派上用场了。

typescript 复制代码
function id<T>(value:T):T {
  return value
}

id<number>(99) // 99
id<string>('hhh') // hhh
id<number[]>([1,2,3]) // [1,2,3]
  • 在函数名称的后面添加<>,其中尖括号里面的T就是类型参数,它用来处理类型而不是值,它可以是任意合法的变量名称
  • 因为T是类型,因此可以将T作为参数和返回值的类型,表示参数和返回值具有相同的类型
  • 由于TS内部会采用一种叫做类型参数推断的机制,来根据传入的数据推断出相对应的类型,针对一些基础数据类型,可以省略不写。比如上述 id<number>(99)可直接写成id(99)id<string>('hhh')可简单写成id('hhh')。当编译器无法推断类型或者推断的类型不准确时,就需要显式的传入类型参数。比如id<number[]>([1,2,3])

单个类型参数 VS 多个类型参数

单个类型参数

typescript 复制代码
function id<T>(value:T):T {
  return value
}
id<number>(99) // 99

顾名思义:类型参数只有一个,如上,只有一个 T

多个类型参数

typescript 复制代码
function swap<T, U>(value: [T, U]): [U, T] {
    return [value[1], value[0]];
}

swap([18, 'age']); // ['age', 18]

多个类型参数之间可进行相互约束

多类型变量之间还可以进行约束,比如第二个类型变量所第一个类型变量约束。

javascript 复制代码
function getPro<T, K extends keyof T> (obj:T, key:K) {
 return obj[[key]
}

getPro({name:'abc',age:18},'age')
getPro('abc','length')
getPro([a,b,c],'length')
  • keyof 接收一个对象类型,生成其键名称或数字的联合类型
  • 类型K受类型T的约束,上述可以理解为K只能是T中所存在的键中任意一个,或者说只能访问对象中存在的属性。

泛型约束

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以导致无法访问它的属性和方法。如下:

javasript 复制代码
function id<T>(value:T):T {
  console.log(value.length) //这段代码编译器会报错:Property 'length' does not exist on type 'T'. 
  return value
} 

上述代码中无法保证传入的数据一定存在length属性。所以,就需要为泛型添加约束。(只允许这个函数传入那些包含 length 属性的变量)

指定更加具体的类型

javasript 复制代码
function id<T>(value:T[]):T[] {
  console.log(value.length)  
  return value
} 

如上、可将T改成T[],也就是T类型的数组,这样数组就一定存在lengh属性,就可以正常访问了。

使用 extends 添加约束

javascript 复制代码
interface TLength {
  length:number
}

function id<T extends TLength>(value:T): T {
   console.log(value.length)  
   return value
}


id(['xxx','yyy'])
id('hhhhh')
id({length:10,name:'abcd'})
  • 创建描述约束的接口TLength,该接口提供length属性
  • 通过extends关键字使用该接口,为泛型添加约束。

泛型接口

接口也可以配合泛型使用

泛型类

泛型工具类型

Partial<Type>

用来创建一个类型,将Type中的所有属性都设置为可选

Readonly<Type>

用来创建一个类型,将Type中的所有属性都设置为只读

Pick<Type,Keys>

从Type中选择一组属性来构造新类型

Record<Keys,Type>

构造一个对象类型,属性键为Keys,属性类型为Type

相关推荐
xiao-xiang11 分钟前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师28 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳2 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?2 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
桂月二二8 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
九酒10 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔10 小时前
HTML5 新表单属性详解
前端·html·html5