typescript 可选链接和strictNullChecks问题

ykejflvf  于 2023-02-17  发布在  TypeScript
关注(0)|答案(2)|浏览(179)

当使用>操作符和一个可选的链接表达式时,我遇到了一个特殊的打字错误。
示例1:if(a?.length === 3)
示例2:if(a?.length > 0)
在上面的两个例子中,假设a被推断为Array<string> | undefined
问题:示例1完全没问题,但是示例2抛出了一个typescript错误TS2532: Object is possibly 'undefined'.。如果我将示例2更新为if(a && a.length > 0),该错误似乎会消失。
我知道这与TS中的strictnullchecks有关,但不知道为什么示例1工作正常,没有抛出错误。这与===>运算符如何求值有关吗?在浏览器控制台中,undefined > 0undefined === 0求值为false。所以我假设在例2中if语句也没有问题,但事实并非如此。
如果有人能告诉我为什么示例2会抛出一个TS错误,我将不胜感激。

lsmepo6l

lsmepo6l1#

What does "all legal JavaScript is legal TypeScript" mean?中所述,TypeScript可能会对它认为不正确的代码发出类型警告。与许多其他语言相比,JavaScript是非常宽松的。并且很乐意允许您使用greater-than > operator来比较两个完全不相关的值,如undefined0。JavaScript规范将undefined > 0解释为NaN > 0(使用"not-a-number" NaN value),而NaNfalse相比,无论如何,undefined > 0在JavaScript中定义良好,但它是“好”JavaScript吗?
这是主观的,但TypeScript的全部意义在于它试图在JavaScript之上覆盖一个静态类型系统,如果JavaScript有更严格的类型系统,它肯定会支持x > y,其中xy都是number。并且在xy都是string的情况下,它也会支持它。但其他任何东西都可能是错误的。或者至少这是TypeScript采取的立场。
如果您重构该比较,以便只在两个数字上使用>,TypeScript会很高兴,比如首先检查a是否正确:

if (a && a.length > 0) { }

在您提到的特定案例中,optional chaining意味着您可能将undefined与一个数字进行比较,microsoft/TypeScript#45543中有一个开放的功能请求需要支持它。它被标记为"等待更多反馈“,这意味着TS团队希望在考虑实施它之前看到更多的需求及其背后的原因。如果您真的希望看到它发生,你可能想给这个问题打个A👍,但务实地说,这不太可能有太大的区别。
在那个问题中提到,如果您现在就想要这个行为,您可以使用非空Assert操作符!来假装可能的-undefined值不是undefined,这将抑制错误:

if (a?.length! > 0) {}

因此,如果您确实需要使用此技术而不是类型安全版本,则可以这样做,而不必等待对语言进行不太可能的更改。
Playground代码链接

5ktev3wc

5ktev3wc2#

对于第一个例子,===同时检查值和类型,所以基本上你检查的是undefined,它是a的相同类型,在可选的链接?之后,所以编译器推断a实际上是未定义的,同时>不能与未定义的值一起使用,所以TS给你这个错误。
你可以通过例如添加一个类型保护if (a)...if(a!.length > 0)来防止这个问题。
希望能有所帮助。

相关问题