尽管检查,对象仍可能为空
2022-05-08
898
为什么 TS 抱怨
Object possibly null
尽管我已经检查过了?
let sum = (data: [...(number | null)[]]): number => {
let result: number = 0;
for (let i = 0; i < data.length; i++)
if(data[i]!==null){
result += data[i]; // here is complain Object possibly null
}
return result;
};
console.log(sum([1, 2, null, 4]));
2个回答
由于这是通过键变量访问对象的属性,因此 TS 无法识别这两个语句引用的是同一个值。您可以将值存储在临时常量中以解决此问题:
const item = data[i];
if (item !== null) {
result += item;
}
但无论如何,我不建议使用
for
循环。要么使用
for ... of
,要么使用
filter
和
reduce
的函数式方法。
for (const item of data) {
if (item !== null) {
result += item;
}
}
各种类型的访问示例,无论正确与否都可能导致错误:
const o = {
x: 12 as number | null,
}
let key = 'x' as keyof typeof o;
if (o.x != null) {
console.log(o.x + 1); // OK
}
if (o.x != null) {
doSomething();
console.log(o.x + 1); // Wrong but allowed
}
if (o[key] != null) {
console.log(o[key] + 1); // Error
}
function doSomething() {
o.x = null;
}
const arr: (number | null)[] = [12];
if (arr[0] != null) {
console.log(arr[0] + 1); // OK
}
if (arr[0] != null) {
doSomething2();
console.log(arr[0] + 1); // Wrong but allowed
}
let i = 0;
if (arr[i] != null) {
console.log(arr[i] + 1); // Error
}
function doSomething2() {
arr[0] = null;
}
brunnerh
2022-05-08
WARNING: If the iterable object has a similar getter, then the first check in the if condition will call it once and then the assignment will call it a second time. The value can change between the if and the assignment. e.g.:
Math.random() > 0.5 ? null : 42
您可以使用 非空断言 :
result += data[i]!;
因为在这个上下文中你可以 100% 地说这不是空的。
Lars Flieger
2022-05-08