TypeScript中泛型函数

2023-12-07 10:52
文章标签 typescript 中泛 型函数

本文主要是介绍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) => stringconst 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 | numberfunction mergeArr<E> (arr1: E[],arr2:E[]) {return [...arr1,...arr2]
}const arr = mergeArr<typeValue>([1,2,3],['a','b','c'])

三.总结

泛型的好处:

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

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

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

这篇关于TypeScript中泛型函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/465587

相关文章

【线性代数】正定矩阵,二次型函数

本文主要介绍正定矩阵,二次型函数,及其相关的解析证明过程和各个过程的可视化几何解释(深蓝色字体)。 非常喜欢清华大学张颢老师说过的一段话:如果你不能用可视化的方式看到事情的结果,那么你就很难对这个事情有认知,认知就是直觉,解析的东西可以让你理解,但未必能让你形成直觉,因为他太反直觉了。 正定矩阵 定义 给定一个大小为 n×n 的实对称矩阵 A ,若对于任意长度为 n 的非零向量 ,有 恒成

创建 typescript 项目.md

有时候需要创建一个最简单的 typescript 项目来验证一些东西,这里记录一下如何创建一个最简单的 typescript 项目。 创建并初始化项目 $ mkdir my-typescript-project$ cd my-typescript-project$ npm init -y$ npm install typescript ts-node @types/node --save

TypeScript数据结构与算法系列(一) —— 链表

TypeScript目录 链表常用操作1.初始化链表2. 插入节点3. 删除节点4. 访问节点5. 查找节点 图源:你好算法 内存空间是所有程序的公共资源,在一个复杂的系统运行环境下,空闲的内存空间可能散落在内存各处。我们知道,存储数组的内存空间必须是连续的,而当数组非常大时,内存可能无法提供如此大的连续空间。此时链表的灵活性优势就体现出来了。 链表(linked list)

VueSax-解决Vue3报错问题,并支持typescript

以下为坑点 根据官方提示,本人在vue3+typescript的项目中添加了vuesax的组件依赖 根据正常的导入依赖思路编写代码,发现typescript一直报 查询vuesax的目录文件发现存在ts文件,于是乎觉得是自己的问题,就查阅gpt与网上资料,查了一晚上加入各种方法,都没有解决,于是乎选择javascript进行测试,发现还是不行! js里虽然不报错,但是在页面

Vue3 + TypeScript 实现防抖(Debounce)和节流(Throttle)

在Vue3项目中结合TypeScript使用防抖(Debounce)和节流(Throttle)技术,可以有效提升应用的性能和用户体验,尤其是在处理频繁触发的事件(如滚动、窗口大小调整、输入框内容变化等)时。下面将详细介绍这两种技术的原理、使用方法以及适用场景。 一、防抖(Debounce) 原理: 防抖技术通过延迟函数的执行来减少函数的调用频率。在事件被触发n秒后再执行回调,如果在这

Typescript实现react-redux的useSelector和useDispatch的状态定义

背景:react中使用typescript,在引入redux之后很多状态定义有问题,记录下来(文章记录学习react-redux过程中的踩坑)。 1.useSelector时,state语法报错,类型为unknown,如下图 我的store状态设置的很简单,两个模块导出,只在state中定义了一个基础类型 在组件中使用useSelector取state中的值,然后报state类型未知 我

TypeScript中的函数与类

TypeScript中的类 传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 使用TypeScript,我们允许开发者现在就使用这些特性,

问:说说Java中泛型,怎么用?

泛型在Java中是一个非常重要的特性,它允许在编译时进行类型检查,从而避免了运行时的类型转换异常。通过泛型,我们可以创建可重用的组件,这些组件可以工作于多种数据类型,同时保持类型安全。 下面,通过示例说明在不同集合类的场景下泛型的具体用法: 使用泛型ArrayList import java.util.ArrayList;import java.util.List;public class

Typescript 常用变量类型声明

函数声明变量 // 基础类型(number、boolean、string)const int = (arg1: number) {// ...}// 数组类型const arr1 = (arg1: number[]) {// ...}// 另一种写法,使用泛型const arr2 = (arg1: Array<number>) {// ...}// 任意类型(any)// a

函数指针变量与指针型函数区别

函数指针变量定义的一般形式: 类型说明符 (*指针变量名)() 其中,“类型说明符”表示被指函数的返回值类型。“(*指针变量名)”表示*后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数。 例如:int (*pf)();表示pf是一个指向函数入口的指针变量,该函数的返回值是整形。   指针型函数的一般形式: 类型说明符 *函数名(形参列表){………………} 其中函数