不能比标题中的内容更好地解释它,所以这里有一个例子:
declare class myClass {
myMethod(num: number): number; // declaration 1
myMethod(str: string, num: number): number; // declaration 2
}
let func1: myClass['myMethod'] = (num: number) => 0;
let func2: myClass['myMethod'] = (str: string, num: number) => 0;
上面的代码没有编译,输出以下错误:
error TS2322: Type '(num: number) => number' is not assignable to type '{ (num: number): number; (str: string, num: number): number; }'.
Types of parameters 'num' and 'str' are incompatible.
Type 'string' is not assignable to type 'number'.
error TS2322: Type '(str: string, num: number) => number' is not assignable to type '{ (num: number): number; (str: string, num: number): number; }'.
如果我评论以下任何一个:
编译成功。
在某些开源软件包的声明文件中,经常会发生同一方法的多次声明aws-sdk
。
多个函数或方法声明描述了重载。重载的函数或方法具有一个或多个调用签名,这些签名是类型声明的一部分。您可以将这组呼叫签名表示为接口/类/作用域中的重复函数/方法/可调用签名,或者表示为所有呼叫签名的交集。一个重载的函数必须可以通过调用签名描述的每种方式来调用。
当实现重载的函数或方法时,您将使用从外部看不到的单个实现签名...这是函数的实现细节。但是实现签名需要能够处理所有调用签名。如果不能,那么您有问题。
我将您的代码重写为单个重载函数接口MyMethod
:
interface MyMethod {
(num: number): number; // declaration 1
(str: string, num: number): number; // declaration 2
}
let func1: MyMethod = (num: number) => 0; // error
let func2: MyMethod = (str: string, num: number) => 0; // error
这基本上与您的代码相同,并且存在相同的问题。func1
是不是有效的MyMethod
。您只能打电话func1(123)
,但不能打电话func1("abc",123)
。但MyMethod
必须同时支持这两个呼叫。同样,func2
仅支持第二个呼叫签名,不支持第一个。
现在考虑一下:
let funcBoth: MyMethod = (strOrNum: string | number, num?: number) => 0; // okay
这样编译就可以了。这是因为的实现签名funcBoth
可以支持likefuncBoth(123)
和like的调用funcBoth("abc", 123)
:
funcBoth(123); // okay
funcBoth("abc", 123); // okay
现在,实现签名也将支持被称为like funcBoth(123, 456)
,但是funcBoth
as的注释MyMethod
不允许您这样做:
funcBoth(123, 456); // error! bad first argument
因此,实现签名对调用者是隐藏的,因此在函数实现内部,您可以放心地依靠调用者不会传入意外参数这一事实。
如果您想要调用的行为func1
或func2
取决于funcBoth
调用的方式,则必须通过检查参数来自己调度:
let f1 = (num: number) => 0;
let f2 = (str: string, num: number) => 0;
let f12: MyMethod = (strOrNum: string | number, num?: number) =>
typeof strOrNum === "number" ? f1(strOrNum) : f2(strOrNum, num!);
好吧,希望能有所帮助;祝好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句