当前位置: 首页 > article >正文

TypeScript中泛型函数

一.概览

此前,对泛型有了整体的概览,详见TypeScript中的泛型,后面的系列会详细地介绍TypeScript的泛型。此篇文章主要介绍泛型函数

二. 泛型函数

泛型是类型不明确的数据类型,在定义时,接收泛指的数据类型(不知道具体是什么类型),在使用时,指定明确的数据类型的一种给定类型的方式。

泛型定义的位置:

  1. 函数声明: 写在函数名后面;
  2. 函数表达式: 写在表达式最前面

泛型调用的位置
在函数名后面跟泛型
传入具体的数据类型![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/70597a0664884784b3270b4e7e35e70a.png

1.泛型函数的引入具体是为了解决什么问题呢?

举个例子

function getSplitValue(value: string[],type: string):string {
    return value.join(type)
}

function getSplitValue2(value: number[],type: string):string {
    return value.join(type)
}

getSplitValue(['1','2','3'],',')
getSplitValue2([1,2,3],',')

问题:两个函数内部的逻辑完全一样,但由于传递参数的类型不同,导致了不得不定义两个函数去处理两个不同类型的数组

解决方案:用一种类型兼容两种不同类型的数组

第一种方法,可以使用any

value: any[]

缺点:如果想在使用函数时明确数组元素类型时,any就不适合了,用any会使约束变小

第二种方法: 使用泛型

function getSplitValue3<E>(value: E[],type: string):string {
    return value.join(type)
}

const aa = getSplitValue3<string>(['a','b','c'],',')
const bb = getSplitValue3<number>([1,2,3],',')
console.log(aa) // 'a,b,c'
console.log(bb) // '1,2,3'

最小范围为any的场景,基本上都可以使用泛型

2. 泛型函数复用

type TypePlus<T> = (a: T, b: T) => T
type TypeNumberPlus<T,U> = (a: T, b: U) => string

const plusNumber: TypePlus<number> = (a,b) => {
    return a + b
}

const plusString: TypePlus<string> = (a,b) => {
    return a + b
}
const numberPlus: TypeNumberPlus<number,string> = (a,b) => {
    return a + b
}
console.log(plusNumber(1,2))
console.log(plusString('1','2'))
console.log(numberPlus(9,'aa'))

可以将公共部分封装起来,有点像js中的柯里化。

3. 泛型约束

举个例子

function plusNumber(a: number,b:number):number {
    return a + b
}

指定特定类型,正常编译

function plusNumber<T>(a: T,b:T):number {
    return a + b
}

指定泛型,编译报错
编译报错:运算符“+”不能应用于类型“T”和“T”

报错原因:它们可以是任何类型(由泛型 T 表示),然后返回这两个参数的和。
但是,有一个问题在于,这个函数不能正确处理所有类型的参数。当输入参数的类型不是数字或时,尝试将它们相加将会导致运行时错误,所以需要约束

function plusNumber<T extends number>(a: T, b: T): number {  
    return a + b  
}
plusNumber<number>(1,2)

类似的例子还有这种

function getLength<T>(value: T) {
    return value.length
}

编译报错:类型“T”上不存在属性“length”

报错原因:泛型T作为getLength的泛型参数的类型范围大了,某些数据类型是没有length属性,导致无法进行length的访问

可以用泛型约束来修复

function getLength<T extends {length: number}>(value: T) {
    return value.length
}

注意:函数约束是为了让范围的可代表类型的范围缩小,并不是给泛型指定类型。

可迭代的对象,才可以进行对应的数据转换


interface IPrev<U> {
[key:number]:U
}


function createObject<T extends Iterable<any>>(value: T) {
return [...value].reduce((prev:IPrev<U>,current:U,index:number) =>{
prev[index] = current
return prev
},{})}

4. 泛型的联合类型

举个例子

function mergeArr<E> (arr1: E[],arr2:E[]) {
    return [...arr1,...arr2]
}

const arr = mergeArr<number>([1,2,3],['a','b','c'])

类型推断: 根据第一个实参[1,2,3]推断E为number,所以[‘a’,‘b’,‘c’]里面的值为字符串的时候会有编译报错
编译报错:不能将类型“string”分配给类型“number”。

这个时候就可以使用联合类型

type typeValue = string | number

function mergeArr<E> (arr1: E[],arr2:E[]) {
    return [...arr1,...arr2]
}

const arr = mergeArr<typeValue>([1,2,3],['a','b','c'])

三.总结

泛型的好处:

  1. 可以在不明确类型的时候,使用泛型占位
  2. 可以在调用函数是,对函数的参数进行类型的约束

类型参数化是泛型的特征:

  1. 定义时,传入类型参数(泛型)
  2. 调用时,传入实际类型

http://www.kler.cn/news/160929.html

相关文章:

  • 在Azure虚拟机中使用XDP Native模式
  • 批量AI人工智能写作软件下载【2024最新】
  • 【ROS问题】rosrun python 文件的时候,指定不同的python编译器
  • Vue系列:Vue Element UI中,使用按钮实现视频的播放、停止、停止后继续播放、播放完成后重新播放功能
  • GUI菜单栏
  • GitLab 服务更换了机器,IP 地址或域名没有变化时,可能会出现无法拉取或提交代码的情况。
  • C++初学者线路图 23年12月
  • Go 语言中的函数调用。
  • Linux学习笔记7-SPI的应用和ICM-26068
  • 用心整理的免费API集合
  • 微表情检测(二)----SOFTNet论文总结
  • 虚拟数据优化器VDO
  • 关系数据库和非关系数据库相机
  • 头歌题目-数组
  • 深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
  • Rust编程语言入门教程(三)-trait
  • jQuery ajax读取本地json文件 三级联动下拉框
  • 【Java基础系列】JavaWeb入门
  • Linux CentOS本地部署SQL Server数据库结合cpolar内网穿透实现公网访问
  • 编译器和 IR:LLVM IR、SPIR-V 和 MLIR
  • QT linux下使用Qt Creator调试附加进程,加快调试
  • 大量 SVG 图标在 React 中的极速集成与应用
  • Windows精品必备工具,总有一款适合你
  • cesium 融合视频
  • Redis 数据的持久化 RDB、AOF、RDB + AOF、No persistence 各自优缺点
  • 程序员如何开发高级python爬虫?
  • 从零开始,利用ChatGPT学会写作的完整指南
  • idea报错——Access denied for user ‘root‘@‘localhost‘ (using password: YES)
  • 使用xshell连接虚拟机(服务器)
  • 阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来