TypeScript细碎知识点:TS中的函数重载,方法重载,构造器重载
理解重载
用于实现不同参数输入并且对应不同参数输出的函数,在前面定义多个重载签名,一个实现签名,一个函数体构造,重载签名主要是精确显示函数的输入输出,实现签名主要是将所有的输入输出类型做一个全量定义,防止TS编译报错,函数体就是整个整个函数实现的全部逻辑。

函数重载
🌰应用例子:
一个班级有很多学生,老师要查询学生的用户信息,如果是输入数字就通过排名(id)去匹配,输入的是字符串就通过分数(grades)去匹配,用TS模拟这种情况。
首先定义用户类型
type User = { id: number, name: string, age: number, grades: number }
班级用户信息数据
const userList: User[] = [ { id: 1, name: '小明', age: 20, grades: 98 }, { id: 2, name: '小李', age: 24, grades: 88 }, { id: 3, name: '小张', age: 21, grades: 99 }, { id: 4, name: '小王', age: 28, grades: 78 }, ]
1.普通实现思路
通过联合类型来做输入定义,输出定义。输入number是(id)是唯一的名次,使用find;输入string是(grades)可能有重复的,使用filter。
function getUserInfo(value: number | string): User | User[] { if (typeof value === 'string') { return userList.find(item => item.id === value) /*error: 不能将类型“User | undefined”分配给类型“User | User[]”。 不能将类型“undefined”分配给类型“User | User[]”。*/ } else { return userList.filter(item => item.grades === value) } }
这样定义TS会报一个异常
❌error:不能将类型“User | undefined”分配给类型“User | User[]”。不能将类型“undefined”分配给类型“User | User[]”。
原因切到底层find方法源码,发现是find可能返回的undefined类型
⭕️ 解决方式很简单,返回类型再联合一个undefined即可解决。
缺点:缺点很明确,都是通过联合类型输入输出,明明知道number输入一定返回User,string输入一定返回User[],这样返回不明确输入什么返回什么,很多时候我们看方法的定义的时候就想看输入啥返回啥,更好的判定类型,为了解决这个函数重载出现了
2.函数重载实现思路
TS的函数重载主要分为 “多个重载签名 + 实现签名 + 函数体”
简单理解来看实现签名主要是之前普通实现思路的情况,TS编译的时候检查所有类型和函数体中的对比检查是否存在。实现签名和函数体检查通过后,执行函数的时候实际上是某个重载签名+函数体,跳过了实现签名。
🔔:通过鼠标点击实际调用方法
getUserInfo(2),command+鼠标右键,他会自动解析跳转到number这个重载签名上面去,很直观的知道如何调用的。
需求变更: 现在查询相同分数太多,老师输入string想添加一个变量count用于控制查询数量。
修改步骤:第二个重载签名和实现签名添加count定义,函数体书写count逻辑,但是TS报出一下错,意思是实现签名传了两个值,第一个重载签名却只有一个值。
解决办法:那么只有在实现签名增加一个count默认值即可。
方法重载
方法重载和函数重载其实差不多,还是方法重载是放在类里面的
🌰应用例子:
简单封装一个数组,使数组更加好用,通过index删除返回index,通过object删除返回object
class ArrayEN { constructor(public arr: object[]) { } get(index: number) { return this.arr[index]; } delete(value: number): number; delete(value: object): object; delete(value: number | object): number | object { this.arr = this.arr.filter((item, index) => { if (typeof value === "number") { return value !== index; } else { return value !== item; } }); return value; } }
构造器重载
先来理解构造器constructor的原理,构造器是没有返回值的,他会隐式返回一个this,这个this会分配给new对象的左边的变量,至此所有的this都是指向的当前正在使用的对象。
构造器重载和函数重载使基本相同,主要区别是:
⏰ TS 类构造器重载签名和实现签名都不需要管理返回值,TS 构造器是在对象创建出来之后,但是还没有赋值给对象变量之前被执行,一般用来给对象属性赋值。
🌰应用例子:
现在要求算一个图片的面积,这个图形可能是传参可以是对象也可能是长宽
interface OJType { width?: number, heigth?: number } class Graph { public width: number; public heigth: number; constructor(width?: number, height?: number) constructor(side?: OJType) constructor(v1: any, v2?: any) { if (typeof v1 === 'object') { this.width = v1.width; this.heigth = v1.height; } else { this.width = v1; this.heigth = v2; } } getArea() { const { width, heigth } = this return width * heigth } } const g = new Graph(10, 10) console.log(g.getArea());
主要实现思路:
通过构造器将类型定义出来,首先是带有长宽对象的类型,这里才用接口的形式定义,然后就是width,heihgt的number类型,最后简单的通过typeod判断对象类型然后进行赋值,综上发现不管是函数重载,方法重载,构造器重载都是异曲同工之妙,只是需要注意使用场景就行。
浙公网安备 33010602011771号