Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript:如何获取和使用具有多个声明的类方法的类型_Typescript - Fatal编程技术网

TypeScript:如何获取和使用具有多个声明的类方法的类型

TypeScript:如何获取和使用具有多个声明的类方法的类型,typescript,Typescript,无法比标题中的内容更好地解释它,因此下面是一个示例: 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['myMeth

无法比标题中的内容更好地解释它,因此下面是一个示例:

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; }'.
如果我对以下任何一项进行评论:

  • 声明1和功能1或
  • 宣言2和宣言2
编译成功


同一方法的多个声明在某些开源软件包的声明文件中非常常见,例如,
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
这个编译得很好。这是因为
funcall
的实现签名可以支持调用like
funcall(123)
和like
funcall(“abc”,123)

现在,实现签名也支持像
funcall(123456)
那样调用,但是
funcall
作为
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!);

好吧,希望这会有帮助;祝你好运


惊人的答案。谢谢
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!);