typescript - 函数重载

156 阅读2分钟

函数重载,适用于完成某种功能,但是实现细节又不相同的场景。下面使用一个简单的例子来提现函数重载的优势

需求:实现一个函数,根据传入参数的类型,来查找以下数组中对应的结果

  • 如果传入数字,则查找 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)

image.png 可以看到,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 })
  }
}

image.png 可以看到,使用函数重载,就可以完美的推导出返回类型

函数重载的一些语法,概念

函数重载使用起来不复杂,但是有一些前置知识是需要了解的

image.png
实现签名:靠近函数体的函数签名,只能有一个
重载签名:实现签名上方的函数签名,可以有多个

  • 调用函数时,只能调用重载签名,不能调用实现签名。实现签名只是起到一个总览作用
  • 重载类型的参数类型和返回值类型必须有,且要和实现签名兼容。因此,我们可以在实现签名使用 any 而不会影响代码推导和可读性

总结:函数重载的优点

  1. 结构分明,可以一眼看出不同入参对应的返回类型,而不必去看函数实现
  2. 完美推导,可以根据入参,推导出不同情况下的返回值,提高开发效率

这是学习笔记,课程出处慕课网课程