打字稿“对象可能为'null'”错误警报

时间:2020-03-25 10:51:09

标签: typescript

我有以下代码:

isEmpty(vehicle: VehicleTitle) {
    return this.options && this.options[vehicle.type] && this.options[vehicle.type].length === 0;
}

IDE(VSCode)指向this.options[vehicle.type].length并说

对象可能为“空”

您不认为这是一个错误的警报吗?怎么了?

编辑

最小的可复制示例here

1 个答案:

答案 0 :(得分:3)

这似乎是TypeScript中的错误!

Here is a previous bug along these lines该错误已在2019年7月修复,但受影响的行为是:

const obj: { [key: string]: any[] | null }  = { prop: [] };

obj["prop"] && obj["prop"].length; //error
obj.prop && obj.prop.length; //OK

从3.6.0版开始,情况不再如此,并且接受了这两行。似乎现在存在一个稍微不同的问题,但其轮廓是相同的:

const obj: { [key: string]: any[] | null }  = { prop: [] };

const key = "prop" as const;
obj[key] && obj[key].length; //error
obj.prop && obj.prop.length; //OK

使用任何变量(甚至是常量)进行属性访问时,TypeScript都会报告与以前相同的错误。

有一个similar older bug与括号符号有关,通常不会与点符号相同。该公寓于2018年8月关闭,但已在12天前重新开放(2020年匹配)。看来,团队已经意识到了这个问题,并正在重新研究后一个问题。

同时,以下几种避免编译错误的方法:

使用非空断言

您只需使用后缀!来执行non-null assertion,就可以解决问题:

isEmpty(vehicle: VehicleTitle) {
  return this.options && this.options[vehicle.type] && this.options[vehicle.type]!.length === 0;
//                                                                               ^
}

Playground Link

使用中间变量进行检查

如果要避免断言,可以只获取值然后使用它。这样可以确保编译器实际上并没有获取两个不同的值:

isEmpty(vehicle: VehicleTitle) {
  const value = this.options && this.options[vehicle.type];
  return value && value.length === 0;
}

Playground Link

使用可选链接

Typescript还具有称为optional chaining的功能,可以为您执行相同的检查。每个可能不存在的属性后面都有一个后缀?

isEmpty(vehicle: VehicleTitle) {
  return this.options?.[vehicle.type]?.length === 0;
//                   ^               ^
}

Playground Link