编译器可以推断出你的代码是什么does,但它不知道你做什么intended。举个简单的例子:
function thing(value: string) {
return value === "foo" ? 123 : "456";
}
推断的类型是function thing(value: string): 123 | "456"
,这与实现相匹配,但这在任何有意义的意义上都是如此right?也许我打算总是返回一个number
, 例如;如果我告诉编译器,它可以告诉我我没有:
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.(2322)
特别是当您使用复杂的包装器/通用类型时(例如,我在angular /questions/tagged/angular在使用 RxJS 可观察量的地方),这确实可以帮助您尽早获得关于您的假设的反馈。
我还经常从事测试驱动开发(TDD)方面的工作,其中在实现之前编写测试的价值之一是,它使您有机会在更改接口的成本接近于零的情况下讨论接口。使用经典的 RPS 示例:
function rps(left: string, right: string) {
return "right";
}
it("returns 'right' for 'rock' vs. 'paper'", () => {
expect(rps("rock", "paper")).to.equal("right");
});
这将编译并通过,但这就是我们想要的吗?want?现在我们可以讨论选项:
-
我们接受推断的类型吗function rps(left: string, right: string): string
?
-
更具体一些,例如
type Throw = "rock" | "paper" | "scissors";
type Outcome = "left" | "right" | "draw";
function rps(left: Throw, right: Throw): Outcome { ... }
-
Use enums https://www.typescriptlang.org/docs/handbook/enums.html反而?
我们可以讨论权衡,并根据我们当时所知道的情况选择最佳选择。显式返回类型用作文档我们做出的决定。
我建议制作@typescript-eslint/explicit-function-return-type https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/explicit-function-return-type.md如果您对代码进行 linting,则会出现错误,其理由如下:
函数返回值的显式类型使任何人都清楚
调用代码返回什么类型。这保证了返回值
被分配给正确类型的变量;或者在这种情况下
没有返回值,调用代码不会尝试使用
不应该的未定义值。