【发布时间】:2022-12-22 14:47:10
【问题描述】:
我只是注意到,如果我在缩小类型时使用 length 属性,打字稿不知道变量不为空:
declare const foo: { method: () => void, groups: number[] } | undefined;
if (foo?.groups.length > 0) {
foo.method();
}
这给你一个错误,说这个对象可能是未定义的。如果您删除长度检查,那么它会按预期工作。 这是TS限制吗?预期的行为?不好的做法?
【问题讨论】:
-
这段代码无论如何都有类型错误,因为
foo?.groups.length可以是undefined,所以它不一定能与0相提并论。通常,Typescript 仅在条件具有几种特定形式之一时才进行类型缩小,详细信息参见此处的文档:typescriptlang.org/docs/handbook/2/narrowing.html -
数组上的长度如何未定义? groups 属性不是可选的,因此只要它不是未定义的并且它是预期的对象,groups 就是一个数组
-
根本不一定有数组。如果
foo未定义,表达式foo?.groups.length将被计算为undefined。当然,只要它不是 undefined 那么结果就不是 undefined,但是如果它是undefined 那么它将是 undefined ... -
那不是问题。 Undefined 不大于 0,因此它求值为 true 的唯一机会是 length 是一个大于 0 的数字,此时 foo 已定义。
-
是的,
undefined与 Javascript 中的0相当,但在 Typescript 中这是类型错误,因为程序员实际上通常不想比较undefined以查看它是大于还是小于数字。该错误与类型缩小无关,只是您使用可能未定义的值与数字进行比较。如果你写let a = 5 + foo?.groups.length;,你会得到类似的错误,因为是的,Javascript 允许你做5 + undefined,但 Typescript 的工作是告诉你,如果你的代码可以做到这一点,那可能是一个错误。
标签: typescript