函数重载,适用于完成某种功能,但是实现细节又不相同的场景。下面使用一个简单的例子来提现函数重载的优势
需求:实现一个函数,根据传入参数的类型,来查找以下数组中对应的结果
- 如果传入数字,则查找 messageList 中对应的 id 选项,返回该对象
- 如果传入字符串,则查找 messageList 中所有对应的 type,返回对应type的数组
type MessageType = 'image' | 'audio' | string
type Message = {
id : number;
type: Message;
sendmessage: string;
}
let messages: Message[] = [
{
id: 1, type: 'image', sendmessage: "你好啊,今晚咱们一起去三里屯吧",
},
{
id: 2, type: 'audio', sendmessage: "朝辞白帝彩云间,千里江陵一日还"
},
{
id: 3, type: 'audio', sendmessage: "你好!张无忌"
},
{
id: 4, type: 'image', sendmessage: "刘老根苦练舞台绝技!"
},
{
id: 5, type: 'image', sendmessage: "今晚王牌对王牌节目咋样?"
}
]
不用函数重载的实现及使用
function getMessage(value: number | MessageType):Message | Message[] | undefined{
if(typeof value === 'number'){
return messages.find(msg => { return msg.id === value})
}else{
return messages.filter(msg => {return msg.type === value})
}
}
// let msg = getMessage(2).sendmessage
// let msg = (<Message>getMessage(2)).sendmessage
// console.log(msg)
可以看到,getMessage 无法在运行前根据你传入的参数来推导出对应类型,因此会返回所有类型。如果你需要使用 sendmessage 属性,可以使用类型断言,确定这次的执行结果是 Message 类型。
使用函数重载
function getMessage(value: number): Message
function getMessage(value: MessageType): Message[]
function getMessage(value: any) {
if (typeof value === 'number') {
return messages.find(msg => { return msg.id === value })
} else {
return messages.filter(msg => { return msg.type === value })
}
}
可以看到,使用函数重载,就可以完美的推导出返回类型
函数重载的一些语法,概念
函数重载使用起来不复杂,但是有一些前置知识是需要了解的
实现签名:靠近函数体的函数签名,只能有一个
重载签名:实现签名上方的函数签名,可以有多个
- 调用函数时,只能调用重载签名,不能调用实现签名。实现签名只是起到一个总览作用
- 重载类型的参数类型和返回值类型必须有,且要和实现签名兼容。因此,我们可以在实现签名使用 any 而不会影响代码推导和可读性
总结:函数重载的优点
- 结构分明,可以一眼看出不同入参对应的返回类型,而不必去看函数实现
- 完美推导,可以根据入参,推导出不同情况下的返回值,提高开发效率
这是学习笔记,课程出处慕课网课程