【问题标题】:typescript overloading class methods - same return type, different parameters打字稿重载类方法 - 相同的返回类型,不同的参数
【发布时间】:2015-10-26 22:51:41
【问题描述】:

我有一个打字稿类:

class ContactModel {

    public getUsage(type: string): restangular.IElement {
      return this.getBase().one('usages', type);
    }

    public getUsage(customerId: number, type: string): restangular.IElement {
      return this.ModelFactory.createRequestMapper(ContactModel.options)
        .one('customers', customerId).all('contacts/usages', type);
    }

    //...
}

导致编译器抛出以下错误:

>> app/modules/common/model/ContactModel.ts(27,12): error TS2393: Duplicate function implementation.
>> app/modules/common/model/ContactModel.ts(31,12): error TS2393: Duplicate function implementation.

我看到的这个例子和TypeScript Handbook 的唯一区别是它们的例子有不同的返回类型,而我有相同的返回类型(两种情况都有不同的输入参数)。

问题是:我做错了什么 - 还是打字稿类方法需要具有不同的方法参数类型才能允许重载?这似乎很愚蠢,因为 .Net 和 Java 都支持使用相同的返回类型和不同的输入类型进行重载。

【问题讨论】:

  • 将 customerId 参数作为可选参数放在 getUsage 的末尾可能会更好,并且只保留一个公共 getUsage 方法,然后您可以在内部检查 customerId 是否具有默认值,如果没有,请在函数调用中使用它。 ps,您对 .net 和 java 的评论是不相关的,因为它是在 javascript 中编译的,并且是未知的
  • @Icepickle 感谢您的评论。我的反驳意见:[1] 我的问题不是我能做什么(使代码编译),而是关于 TS 中允许的内容和不允许的内容 - 或者编译错误的原因是什么,[2] 评论 是相关的,因为它与一种语言的语法有关,并且是否将某些内容转换为其他内容都没有关系。我很确定可以修改 TS 以允许该功能。 重载 是 C、C++、C#、Java 中已知的东西。并且不同的输入参数足以在那里使用重载。
  • 好吧,当然,对于一个知道如何使用重载的语言,你会如何将这样一个直接的语句翻译成 javascript?在 javascript 中(除了参数)没有直接访问,你的方法签名和你如何调用它(尽管 TypeScript 可能能够做到这一点,他们也应该做额外的逻辑来根据参数计数进行区分,这不会对我来说听起来不是很安全)
  • @Icepickle 在这种情况下,它应该被称为 quasi-overloading 而不是 overloading 以强调它与正常的重载模式不同人们习惯的方法-这是我的观点:)

标签: javascript typescript


【解决方案1】:

JavaScript 不做运行时类型信息,所以你必须自己做重载消歧。请注意,在手册中的示例中,只有一个函数实现,而您有两个。

class ContactModel {
  public getUsage(type: string): restangular.IElement;
  public getUsage(customerId: number, type: string): restangular.IElement;
  public getUsage(typeOrCustomerId: string|number, type?: string): restangular.IElement {
    if (typeof typeOrCustomerId === 'string') {
      // First overload
      return this.getBase().one('usages', type);
    } else {
      // Second overload
      return this.ModelFactory.createRequestMapper(ContactModel.options)
        .one('customers', customerId).all('contacts/usages', type);
    }
  }
}

【讨论】:

  • 解释清楚。前两个方法只是声明了参数并没有实现。
猜你喜欢
  • 2018-11-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-05
  • 2020-12-28
  • 1970-01-01
相关资源
最近更新 更多