让我们考虑一下这个简单的语句:

var foo = document.getElementById('foo');

if (foo instanceof Element) {
    a.innerHTML = "Some text";
}

但如果你写道:

var foo = document.getElementById('foo');

if (foo instanceof Element === true) {
    a.innerHTML = "Some text";
}

打字脚本转换器抛出一个错误:

'foo' is possibly 'null'.

假设instanceof只能返回TRUE或FALSE,我不明白为什么转换程序不接受带有=TRUE的条件. 相反的语句也有相同的错误:

!(foo instanceof Element)

不同于:

foo instanceof Element === false

这种行为的原因是什么?这两种说法有什么不同吗?

推荐答案

TypeScrip的narrowing / type guarding支持仅适用于某些编码模式.类型判断器无法通过模拟代码流的每个可能的逻辑含义来分析代码;相反,它使用启发式方法来检测在实践中用作类型保护的常见约定.它们必须是常见的,这样缩小范围的好处就超过了在任何地方执行额外判断所产生的成本.(例如,参见微软/TypeScrip#26275上TS团队开发负责人的第this unpopular comment页.)

microsoft/TypeScript#9508有一个更老的问题,它建议expr === trueexpr === false在相同的情况下表现为类型保护,而expr!expr将表现为类型保护.这被关闭了,因为"不会修复"because"在大多数情况下,=== true是一种代码气味,而且出现的频率不足以证明支持它的额外复杂性是合理的."

另一方面,在microsoft/TypeSript#31105有一个问题要求相同的东西,并且它被标记为错误.它在the Backlog上,这意味着没有人一定会go 做它.然而,TS人员通常愿意接受社区对此类积压问题的Pull请求,因此这意味着看到这种变化的最佳方式是让感兴趣的一方提交适当的Pull请求.

除非实施了这种支持,否则继续下go 的最简单方法是简单地执行expr!expr中更常规的判断,如if (foo instanceof Element)if (!(foo instanceof Element)).其他任何事情都会更复杂或更脆弱(例如,写一个custom type guard function)

Typescript相关问答推荐

如何基于对象关键字派生类型?

如何创建泛型类型组件来使用React Native的FlatList或SectionList?'

在将对象从一个对象转换成另一个对象时,可以缩小对象的键吗?

接口的额外属性作为同一接口的方法的参数类型'

如何在TypeScrip中从字符串联合类型中省略%1值

分解对象时出现打字错误

寻址对象中路径的泛型类型

对于始终仅在不是对象属性时才抛出的函数,返回Never

从泛型类型引用推断的文本类型

类型推断对React.ForwardRef()的引用参数无效

界面中数组中的混合类型导致打字错误

创建一个TypeScrip对象并基于来自输入对象的约束定义其类型

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

如果判断空值,则基本类型Gaurd不起作用

为什么TypeScrip假定{...省略类型,缺少类型,...选取类型,添加&>}为省略类型,缺少类型?

有没有一种方法可以防止我的组件包在其中安装样式组件'; node 模块中的s目录

是否使用类型将方法动态添加到类?

如何在 TypeScript 类型定义中简化定义长联合类型

redux-toolkit、createAsyncThunk 错误

将 Angular 从 14 升级到 16 后出现环境变量注入问题