重载
2023年01月12日
一、优势
- 结构分明,让代码可读性,可维护性提升许多,而且代码更漂亮
- 各司其职,自动提示方法和属性,每个重载函数完成各自的功能,输出取值时不用强制转换就能出动自动提示,从而提高开发效率。
- 更利于功能扩展
二、规则
函数重载 一组具有相同的名字,不同的参数列表、不同的返回值的函数。
函数签名 函数签名 = 函数名称 + 函数参数个数 + 函数参数类型 + 返回值类型 四者合成。在TypeScript中,包含了实现签名和重载签名,实现签名是一种函数签名,重载签名也是一种函数签名。
完整的函数重载定义规则如下:
- 规则1: 由一个实现签名 + 一个或多个重载签名合成
- 规则2: 外部调用函数重载定义的函数时,只能调用重载签名,不能调用实现签名。这是因为实现签名下的函数体是给重载签名编写的,实现签名只是在定义时起到了统领所有重载签名的作用,在执行调用时就看不到实现签名了。
- 规则3: 调用重载函数时,会根据传递的参数来判断你调用的是哪一个函数
- 规则4: 只有一个函数体,只有实现签名配备了函数体,所有的重载签名都只有签名,没有配备函数体。
- 规则5: 关于参数类型规则完整总结如下:
- 无论重载签名由几个参数、参数是何种类型,实现签名都可以是一个无参函数签名
- 实现签名参数个数可以少于重载签名的参数个数,但实现签名如果准备包含重载签名的某个位置的参数,那实现签名就必须兼容所有重载签名该位置的参数类型
- 规则6: 关于重载签名和实现签名的返回值类型规则完整总结如下:
- 必须给重载签名提供返回值类型,TypeScript 无法默认推导
- 提供给重载签名的返回值类型不一定为其执行时的真实返回值类型,可以为重载签名提供真实返回值类型,也可以提供 void 或 unknown 或 any 类型。如果重载签名的返回值类型是 void 或 unknown 或 any 类型,那么将由实现签名来决定重载签名执行时的真实返回值类型。当然为了调用时能有自动提示+可读性更好+避免可能出现了类型强制转换,强烈建议为重载签名提供真实返回值类型。
- 不管重载签名返回值类型时何种类型,实现签名都可以返回 any 类型 或者 unknown 类型,当然一般我们两者都不选择,让 TypeScript 默认为实现签名自动推导返回值类型
三、理解
-
通过函数重载实现消息推送功能
使用函数重载,实现消息推送type MessageType = "image" | "audio" | string;
type Message = {
id:number;
type:MessageType;
sendMessage:string;
}
let messages:Message[] = [
{
id:1,
type:'image',
sendMessage: '哈哈哈'
},
{
id:2,
type:'image',
sendMessage: '哈哈哈'
},
{
id:3,
type:'image',
sendMessage: '哈哈哈'
},
{
id:4,
type:'audio',
sendMessage: '嘻嘻嘻'
},
{
id:5,
type:'呵呵呵',
sendMessage: '呵呵呵'
},
]
function getMessage(value:number,property:string):Message|undefined;
function getMessage(value:MessageType,end:number):Message[];
function getMessage(value1:number|MessageType,value2:number|string):Message|Message[]|undefined{
if(typeof value1 === "number" && typeof value2 === 'string'){
return messages.find(item=>{
return item.id === value1;
});
}else if(typeof value1 !== "number" && typeof value2 === 'number'){
return messages.filter(item=>{
return value1 === item.type;
}).slice(0,value2);
}
}
console.log(getMessage(3,'sendMessage'));
console.log(getMessage('image',2));
export {}