搜索词
类型保护 always-false 警告
建议
当类型保护总是为 false 时,受保护的变量在函数体内是类型 never
。虽然你实际上无法在 never
上查找任何属性,但你可以将其传递给任何地方或分配给任何事物,并且绝对没有警告。使用与保护不重叠的参数调用类型保护函数应该产生警告。
用例
我立即的动机是 #24436(评论),其中如果 Number.isFinite
可以写成类型保护(这还需要一个更窄的 number
子类型,例如 #32188 ),那么它可以轻松地允许使用 number|string
调用,但不需要额外的技巧来警告如果使用保证不是 number
的情况。
一般来说,没有很好的理由调用总是为 false 的类型保护。这与总是为 true 的情况不同,在那种情况下防御性编程才发挥作用。
示例
示例:
declare const x: string;
if (isNumber(x)) { // Should warn: "condition is always false"
usePrivate(x);
}
如果 usePrivate
需要一个此范围无法访问以构造的私有类型,那么如果这段代码能 在某个地方 发出警告就好了。然而,目前它只是将 x
缩小到 never
并允许你随心所欲地使用它。
检查清单
我的建议满足以下准则:
- 这不会对现有的 TypeScript/JavaScript 代码造成破坏性的更改
- 我对于这个会破坏多少东西没有很好的感觉,但我预计任何破坏都会暴露出合法的错误。
- 这不会改变现有 JavaScript 代码的运行时行为
- 这个可以在不根据表达式的类型生成不同的 JS 的情况下实现
- 这不是一个运行时特性(例如库功能、JavaScript 输出非 ECMAScript 语法等)
- 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
5条答案
按热度按时间6rqinv9w1#
Playground
guz6ccqo2#
无论如何,Step提到了这一点。
这与总是为真的情况有所不同,即防御性编程发挥作用。
isString()
始终是 真 (根据类型系统),只是之后取反了。g6ll5ycj3#
我认为,将防御性检查始终以始终为真的格式编写是不合理的。你可以很容易地想象这样写:
不清楚这与OP中的情况有何不同。
cx6n0qe34#
这是一个很好的观点,尽管我怀疑这种情况要少得多。总是可以选择将类型转换为unknown,尽管这并不是特别令人满意。对于这个来说,将其视为类型保护器也不太相关,因为它实际上并没有缩小任何东西的范围。
@RyanCavanaugh - 我的潜在动机是你关于想要警告
Number.isFinite(shouldNeverBeANumber)
的评论,这在某种程度上是相似的 - 我认为你在这里的例子更具说服力,因为它涉及到null/undefined,我们自然地理解它们通常是类型系统的可能例外。也许一个更聪明的方法是在
typeguard(x | undefined | null)
始终为false时发出警告。它缺乏一定的对称性,而且通常来说,聪明的做法是不好,但它似乎通过了一点更好的测试...brtdzjyr5#
我猜想有人可能会声明这个检查为
但这似乎没有什么用处;你什么时候需要一个保证为nullish的值呢?如果你不把它当作类型保护器使用...那么这就是它与OP的区别。问题是关于对总是为false的类型 predicate 调用的警告。
我想不出我曾经见过一个类型保护器在正常操作中总是为假的情况。泛型防御性
boolean
检查,当然有,但是没有总是为假的类型保护器。