这似乎是 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