TypeScript 如何做函数重载
平时写JS的时候,是不是经常遇到同一个函数,要处理不同类型的参数?比如有个函数,既要能传数字算面积,又要能传字符串当名字,但JS本身没法明确告诉别人“我这个函数能接几种参数”,别人用的时候很容易传错。TypeScript的函数重载,就是专门解决这个问题的,咱们用生活里的例子一步步说清楚。
什么是函数重载?
先举个生活化的例子:小区门口的便利店,同一个“结账”动作,有人用微信扫二维码,有人用现金递钱,有人刷公交卡,本质都是完成“付款”这件事,但用的“输入方式”不一样。函数重载就像给同一个函数标清楚,它能接哪几种不同的参数,返回对应的值,让代码更懂你,也能帮你提前避免错误。

简单说,函数重载就是在TypeScript里,先把同一个函数能支持的所有参数类型、返回类型都列出来,再写函数的实际实现,相当于给函数“报名”所有可能的用法,TypeScript就会根据你传的参数,自动匹配对应的用法。
怎么写TypeScript的函数重载?
分两步走,先写“重载声明”,再写“函数实现”,用最常见的“用户信息获取函数”举例子:比如这个函数,能传数字(用户ID),返回用户的数字年龄;也能传字符串(用户名),返回用户的字符串昵称,还能同时传ID和昵称,返回组合信息。
第一步:写重载声明
重载声明就是把函数能支持的所有用法,一条条列出来,注意要写在函数实现之前。上面的例子,声明应该这么写:
`typescript
// 重载1:传数字ID,返回年龄
function getUserInfo(userId: number): number;
// 重载2:传字符串用户名,返回昵称
function getUserInfo(userName: string): string;
// 重载3:同时传ID和用户名,返回组合信息
function getUserInfo(id: number, name: string): string;
`
这时候你会发现,这些只是“规则”,还没写具体怎么干活,只是告诉TypeScript:“这个函数能这么用,你按这个规则检查”。
第二步:写函数实现
写完重载规则,要写实际的函数代码,但这里要注意:实现函数的参数类型,得能兼容所有重载的情况,不能直接写死。比如刚才的例子,参数要写成number | string的联合类型,返回值也得兼容几种可能的类型,不然会报错:
`typescript
// 函数实现:参数和返回值要兼容所有重载的情况
function getUserInfo(param1: number | string, param2?: string): number | string {
// 实现逻辑:判断传参情况,返回对应结果
if (typeof param1 === 'number' && param2 === undefined) {
return 18; // 对应重载1:传ID返回年龄
}
if (typeof param1 === 'string' && param2 === undefined) {
return 用户${param1}; // 对应重载2:传用户名返回昵称
}
if (typeof param1 === 'number' && typeof param2 === 'string') {
return ID${param1}:${param2}; // 对应重载3:返回组合信息
}
throw new Error('传参格式不对哦');
}
`
实际用的时候是什么效果?
现在你调用这个函数,TypeScript就会自动匹配对应的重载,不会乱报错了:
- 传数字
getUserInfo(1001),会提示返回number,你拿到的是年龄18,不会有人说“不知道你传的是啥”; - 传字符串
getUserInfo('小明'),会提示返回string,拿到的是“用户小明”; - 传两个参数
getUserInfo(1001, '小明'),会提示返回组合字符串,完全符合我们的需求。
要是你传了个布尔值getUserInfo(true),TypeScript会直接标红,说“这个函数没有支持传布尔类型的重载”,提前帮你揪出错误,不用等代码跑起来才发现。
写函数重载的小提醒
不是所有情况都需要重载,别过度使用。如果只是简单的参数类型不一样,用联合类型就能解决,比如function add(a: number | string, b: number | string),只有当函数的逻辑、返回值类型完全不一样的时候,才用重载,就像便利店的不同付款方式,逻辑不一样,才需要分开声明。
另外,重载的顺序也很重要,TypeScript会从上往下匹配,把最具体的规则写在前面,避免匹配错。比如如果把传字符串的重载写在传数字的前面,传数字的时候就可能匹配错。
这样是不是就把TypeScript的函数重载说清楚了?核心就是先列规则,再写实现,既让代码更规范,又能提前避坑,平时写复杂函数的时候,用这个方法能省不少事。