Typescript 无法识别带有扩展运算符的重载方法

Typescript 无法识别带有扩展运算符的重载方法,typescript,overloading,Typescript,Overloading,我有一个类定义如下: class Test { a(msg: string): string; a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[]} { if (args) { return { msg: msg, args: args }; } return msg; } } 但是,如果执行以下操作,则会出现编译错误: new Test().a(

我有一个类定义如下:

class Test {
  a(msg: string): string;
  a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[]} {
    if (args) {
      return { msg: msg, args: args };
    }
    return msg;
  }
}
但是,如果执行以下操作,则会出现编译错误:

new Test().a("test", "a", 1, 2, 3);
应为1个参数,但得到5个


如何正确重载此方法以为不同的签名提供不同的返回类型?

Typescript不支持使用不同数量的参数进行函数重载

说:

TypeScript提供了函数重载的概念。可以有多个名称相同但参数类型和返回类型不同的函数。但是,参数的数量应相同。
不支持使用不同数量的参数和具有相同名称的类型进行[…]函数重载

实现您正在尝试的目标的一个技巧可能是

interface ReturnA {
    msg: string;
    args: any[];
}

class Test {

  a(msg: string, ...args: never[]): string;
  a(msg: string, ...args: any[]): ReturnA
  a(msg: string, ...args: any[]): string | ReturnA {
    if (args) return { msg, args };
    return msg;
  }

}

const t = new Test();

// only 1 param returns string
const str: string = t.a(`a`); 

// two or more params returns the other object type
const obj: ReturnA = t.a(`a`, `param1`); 

函数实现不是所有可用重载的一部分。相反,你可以写:

class Test {
    a(msg: string): string; // overload 1
    a(msg: string, ...args: unknown[]): { msg: string, args: unknown[] } // overload2
    a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[] } { // impl
       // ...
    }
}

如果你想让重载起作用,你需要为所有函数提供相同数量的参数,对于你的行为,最好选择不同的函数名谢谢你的清晰解释,我不知道我在文档中是怎么漏掉的!我想你可以尝试使用
never
params类型来破解你的示例有趣的破解!输出肯定是我想要的。谢谢你的选择。这引起了我的兴趣,因为文档中指出,不支持使用相同名称的不同数量的参数和类型进行重载。重载1和重载2是不同数量的参数,这是如何工作的?如果你指的是其他链接,回答:老实说,文档作者没有很好地解释TS中的函数重载,并且混淆了实现与类型方面的关系。只需坚持-他们没有说这一点。函数重载是TS特性,可以有不同数量的参数,如您所见。重要的是,函数实现签名与所有重载兼容。不能多次使用相同名称实现函数。顺便说一句:相同的原则适用于方法,如上面的示例所示。
new Test().a("test", "a", 1, 2, 3); // { msg: string; args: unknown[]; }
new Test().a("test") // string