【问题标题】:Why Typescript return type void in interface doesn't trigger error in implementation?为什么接口中的 Typescript 返回类型 void 不会在实现中触发错误?
【发布时间】:2022-01-01 01:48:53
【问题描述】:

我正在 Typescript 游乐场中尝试两个不同的类,它们实现了相同的接口。我不明白为什么接口中返回类型为void 的方法speak() 不会触发错误,如果它的实现返回的不是void。

我必须用返回类型void 显式实现该方法来触发类型检查。对于void 以外的返回类型似乎不会发生这种情况,如下所示。

Snippet in Typescript Playground

interface Person {
  speak(): void;
  walk(): number;
}

export class HumanOne implements Person {
  speak() {
    return 'Hello'; // No type error
  }
  walk() {          // Type error
    return 'Walking';
  }
}

export class HumanTwo implements Person {
  speak(): void {
    return 'Hello'; // Type error
  }
  walk(): number {
    return 'Walking'; // Type error
  }
}

【问题讨论】:

  • void 表示不会使用函数返回的类型(类型会被忽略),参见callback types上的指南
  • “返回类型为 void 的上下文类型不会强制函数不返回某些内容。”详情请见this doc

标签: javascript typescript


【解决方案1】:

没有显式类型声明的方法的推断类型是HumanOne.speak(): string。这与void兼容,有两层含义:

  • 在返回类型为void 的函数实现中,这意味着它不返回任何内容,或多或少相当于将undefined 指定为返回类型。
  • 在函数类型声明中,void 表示可以返回任何东西,并且不能使用调用的返回值。就类型兼容性而言,它或多或少等同于 unknown(但与 unknown 不同,您不能真正传递 void 类型的值)。

这第二个含义也与HumanOne implements Person 的子类型检查相关——() => string 类型是() => void 的子类型(或:可分配给)类型。如果调用Person.speak(),则必须忽略返回值(可能是undefined、字符串或其他任何内容);如果你打电话给HumanOne.speak(),你就会知道你得到了一个字符串。

这在很大程度上是设计使然,请参阅 the docs on Return type voidFAQ entry "Why are functions returning non-void assignable to function returning void?"

【讨论】:

  • 如果我想确保传递给我的函数的回调函数没有返回值并且是一个真正的void 函数,如果() => void 类型与@987654339 类似,我将如何做到这一点@?
  • 然后你会声明你的回调是() => undefined。但我认为没有理由这样做。
猜你喜欢
  • 2018-01-25
  • 2016-11-30
  • 2017-10-14
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 2019-08-21
  • 2019-07-27
相关资源
最近更新 更多