我有一个表示用户查询的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
}
}
}
但是,如果我尝试在forEach
或map
内部使用可选字段,即使在检查了它是否未定义之后,我也会收到一个错误:
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似乎正在"丢失"上下文,即该字段在forEach
或map
调用中未定义。
如何修复此错误?有没有更好的方法来处理这些未定义的字段?谢谢
(以下是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}`);
}
});
}