大多数函数接受一组固定的参数。但是有些函数可以接受可变数量的参数、不同类型的参数,甚至根据调用函数的方式返回不同的类型。为了注释此类函数,TypeScript提供了函数重载。1.函数签名让我们首先考虑一个向特定人返回问候消息的函数。functiongreet(person:string):string{return`Hello,${person}!`;}上面的函数接受1个字符类型的参数:人名。调用函数非常简单:greet('World');//'你好世界!'如果你想让greet()函数更灵活怎么办?例如,让它额外接受一个peopletogreet列表。这样的函数将接受一个字符串或字符串数??组作为参数,并返回一个字符串或字符串数??组。如何注释这样的功能?有两种方法。第一种方法很简单,就是通过更新参数和返回类型直接修改函数签名。以下重构的greet()看起来像:functiongreet(person:string|string[]):string|string[]{if(typeofperson==='string'){return`Hello,${person}!`;}elseif(Array.isArray(person)){returnperson.map(name=>`Hello,${name}!`);}thrownewError('Unabletogreet');}现在我们可以通过两种方式调用greet():greet('World');//'Hello,World!'greet(['Xiaozhi','Daye']);//['Hello,Xiaozhi!','Hello,Daye!']Directupdate是常见的好习惯具有函数签名以支持多种调用方式。然而,在某些情况下,我们可能需要采用另一种方法并单独定义函数的所有调用方式。这种方法称为函数重载。2.函数重载第二种方法是使用函数重载函数。当函数签名比较复杂并且涉及多种类型时,我推荐这种方法。定义函数重载需要定义重载签名和实现签名。重载签名定义函数的形式参数和返回类型,没有函数体。一个函数可以有多个重载签名:对应调用函数的不同方式。另一方面,实现签名也有参数类型和返回类型,还有实现函数体,而且只能有一个实现签名。//重载签名函数greet(person:string):string;functiongreet(persons:string[]):string[];//实现签名函数greet(person:unknown):unknown{if(typeofperson==='string'){return`Hello,${person}!`;}elseif(Array.isArray(person)){returnperson.map(name=>`Hello,${name}!`);}thrownewError('Unabletogreet');}greet()函数有两个重载签名和一个实现签名。每个重载签名都描述了调用函数的一种方式。就greet()函数而言,我们可以通过两种方式调用它:使用字符串参数,或使用字符串参数数组。实现签名函数greet(person:unknown):unknown{...}包含函数如何工作的适当逻辑。现在,如上所述,可以使用字符串类型或字符串数??组类型的参数调用greet()。greet('World');//'Hello,World!'greet(['Xiaozhi','Daye']);//['Hello,Xiaozhi!','Hello,Daye!']2.1重载签名可调用虽然实现签名实现了函数行为,但它不能直接调用。只有重载的签名是可调用的。greet('World');//重载的签名可以调用greet(['小智','大爷']);//重载的签名可以调用constsomeValue:unknown='Unknown';greet(someValue);//ImplementationsignatureNOTcallable//ErrorNooverloadmatchesthiscall.Overload1of2,'(person:string):string',gavethefollowingerror.Argumentoftype'unknown'isnotassignabletoparameteroftype'string'.Overload2of2,'(persons:string[]):string[]',gavethefollowingerror.Argumentoftype'unknown'不可分配给类型为“string[]”的参数。在上面的示例中,即使实现签名接受未知参数,也不能使用类型为unknown(greet(someValue))的参数调用greet()函数。2.1实现签名必须是通用的//重载签名函数greet(person:string):string;functiongreet(persons:string[]):string[];//这个重载签名与其实现签名不兼容。//实现签名函数greet(person:unknown):string{//...thrownewError('Unabletogreet');}重载签名函数greet(person:string[]):string[]与greet(人:未知):字符串不兼容。实现签名的字符串返回类型不够通用,无法与重载签名的字符串[]返回类型兼容。3.方法重载虽然在前面的例子中,函数重载被应用到一个普通的函数上。但是我们也可以在方法重载范围内重载一个方法,重载签名和实现签名都是类的??一部分。例如,我们实现一个带有重载方法greet()的Greeter类。classGreeter{message:string;constructor(message:string){this.message=message;}//重载签名greet(person:string):string;greet(persons:string[]):string[];//实现签名问候(人:未知):未知{if(typeofperson==='string'){return`${this.message},${person}!`;}elseif(Array.isArray(person)){returnperson。map(name=>`${this.message},${name}!`);}thrownewError('Unabletogreet');}Greeter类包含greet()重载方法:2个重载签名描述了如何调用此方法,以及包含正确实现的实现签名。由于方法重载,我们可以通过两种方式调用hi.greet():使用字符串或字符串数??组作为参数。consthi=newGreeter('Hi');hi.greet('小智');//'嗨,小智!'hi.greet(['王大爷','大爷']);//['嗨,王大爷!','Hi,Daye!']4.什么时候使用函数重载函数重载如果使用得当,可以大大增加可能以多种方式调用的函数的可用性。这在自动完成期间特别有用:我们将在自动完成中列出所有可能的过载记录。但是,在某些情况下,建议不要使用函数重载,而是使用函数签名。例如,不要对可选参数使用函数重载://deprecatedfunctionmyFunc():string;functionmyFunc(param1:string):string;functionmyFunc(param1:string,param2:string):string;functionmyFunc(...args:string[]):string{//implementation...}在函数签名中使用可选参数就足够了//推荐做法functionmyFunc(param1?:string,param2:string):string{//implementation。..}5.总结TypeScript中的函数重载让我们可以定义可以多种方式调用的函数。使用函数重载需要定义一个重载签名:一组具有参数和返回类型但没有主体的函数。这些签名指示应如何调用该函数。此外,您还必须编写函数的正确实现(实现签名):参数和返回类型,以及函数体**。请注意,实现签名不可调用。**除了常规函数,类中的方法也可以被重载。作者:dmitripavlutin译者:前端小智来源:dmitripavlutin原文:https://dmitripavltin.com/typeript-function-overloading/【编辑推荐】鸿蒙官方战略合作共建——鸿蒙技术社区如何在MicrosoftSQLServer上恢复SA密码Linux安装MySQL详细教程MicrosoftWindows11/Windows10Office新UI已向所有用户推出:自适应浅色/深色主题、简洁的工具栏盘点Python读取Json文件并提取Json文件内容的四种方式Windows11无论使用它们的时间有多难?让我们谈谈丢失的软件
