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

相关推荐
gqkmiss6 分钟前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃12 分钟前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰16 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
Viktor_Ye22 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm24 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
乐闻x1 小时前
Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
前端·vue.js·性能优化
一条晒干的咸魚1 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
Amd7941 小时前
Nuxt.js 应用中的 webpack:compiled 事件钩子
前端·webpack·开发·编译·nuxt.js·事件·钩子
生椰拿铁You1 小时前
09 —— Webpack搭建开发环境
前端·webpack·node.js
狸克先生1 小时前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互