【发布时间】:2020-02-14 08:58:13
【问题描述】:
我很好奇 Typescript 在考虑可能的执行路径以确定函数的类型时付出了多少“努力”(因为没有更好的术语)。
例如,考虑以下代码:
function getValue() {
if (false) {
return 'never this string';
}
return 42;
}
因为false 永远不会是true,所以永远不会返回“never this string”,因此该函数 - 看起来 - 应该具有“number”类型。
但是,当我将该类型注释(“:数字”)添加到函数定义中时:
// test.ts
function getValue(): number {
if (false) {
return 'never this string';
}
return 42;
}
并编译它(tsc test.ts),我得到这个错误:
test.ts:3:9 - error TS2322: Type '"never this string"' is not assignable to type 'number'.
所以我的问题是:
是否可以让 Typescript 认为“数字”是 getValue 的正确返回类型? (并且,相关的,是否有可能让编译器不会抱怨字符串不能分配给一个数字?)可能还相关:编译 TS 代码时,可以让编译器只删除无法访问的代码和 然后运行它的类型评估?
【问题讨论】:
-
不确定死代码消除是否由 TS 完成。既然您已经提出要求并且我考虑过,我认为它应该完成。考虑一个条件
if (someVar && alwaysFalse),其中alwaysFalse可以通过编程方式确定它总是错误的,但很难手动追踪。现在,您将默默地得到与您(有些错误)期望的不同的行为。如果你依赖类型推断,这反过来会影响其他东西,虽然getValue返回number | string但现在它只返回number,这可能会在其他地方产生影响。 -
假设函数在file1中,在file2内部使用了几次,然后被file3使用。因此,您坐在 file3 中,想知道为什么在为
typeof result == "string"添加案例时会出现错误。您可以绝对收到有关死代码的警告,但即使是 Java 等其他语言也会将您的情况视为错误,因为它们确实会计算死分支的返回值。 -
您甚至不需要
if来创建无法访问的代码;进一步简化为return "test"; return 42;仍然给出"test" | 42的返回类型。而第二个return肯定是无法访问的。 -
你是用
--allowUnreachableCode编译的吗?即使没有number缩小,示例代码对我来说也是一个错误。 -
@jcalz 感谢您指出这一点 - 出于某种原因,当我运行
tsc test.ts时,编译器 (v.3.3) 不会显示无法访问的代码错误,但当我使用tsc -p .时会出现 (即使我的 tsconfig 明确表示"allowUnreachableCode": false,)。
标签: typescript