Typescript丢失带有forEach或map的未定义上下文



我有一个表示用户查询的Typescript接口。因此,它包含大多数可选字段:

interface InputData {
fieldOne?: {
requiredField: {
key: string;
values?: string[];
}
}
fieldTwo?: {
etc?: string;
}
}

使用带有Typescript的--strictNullChecks标志,我必须确保在访问它之前每个属性都没有定义:

function do_something(input: InputData): void {
const messages: string[] = [];
if (input.fieldOne !== undefined) {
if (input.fieldOne.requiredField.values !== undefined) {
console.log(input.fieldOne.requiredField.values):
// no errors
}
}
}

但是,如果我尝试在forEachmap内部使用可选字段,即使在检查了它是否未定义之后,我也会收到一个错误:

if (input.fieldOne !== undefined) {
if (input.fieldOne.requiredField.values !== undefined) {
input.fieldOne.requiredField.values.forEach(v => {
messages.push(`${v} ${input.fieldOne.requiredField.key}`);
// error!
});
}
}

"input.fieldOne"|对象可能未定义。(2532(

在这里,Typescript似乎正在"丢失"上下文,即该字段在forEachmap调用中未定义。

如何修复此错误?有没有更好的方法来处理这些未定义的字段?谢谢

(以下是Typescript Playground中此错误的链接。(

使用Non-Null断言运算符(!(。你会告诉打字脚本编译器:"相信我,我知道我在做什么。">

console.log(input.fieldOne!.requiredField.values):

另一种方法是在forEach语句之前创建另一个变量,其中typescript编译器仍然信任if作用域:

if (input.fieldOne) {
const requiredField = input.fieldOne.requiredField;
requiredField.values.forEach(v => messages.push(`${v} ${requiredField.key}`));
}

第三种方法是在forEach循环内重新测试input.fieldOne。不过这会导致性能下降:

if (input.fieldOne) {
input.fieldOne.requiredField.values.forEach(v => {
if (input.fieldOne) {
messages.push(`${v} ${input.fieldOne.requiredField.key}`);
}
});
}

最新更新