【问题标题】:Typescript loses undefined context with forEach or mapTypescript 使用 forEach 或 map 丢失未定义的上下文
【发布时间】:2020-04-28 06:58:43
【问题描述】:

我有一个代表用户查询的 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 调用中未定义的上下文。

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

(Here is a link to this error in the Typescript Playground.)

【问题讨论】:

    标签: javascript typescript


    【解决方案1】:

    使用Non-Null 断言运算符 (!)。你会告诉 typescript 编译器:“相信我,我知道我在做什么。”

    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}`);
        }
      });
    }
    

    【讨论】:

    • 谢谢!似乎这回避了strictNullChecks 标志,是否有更“合规”的解决方案?在我当前的项目中,我做了很多重构,以更好地尊重编译器严格的空检查能力。
    • 我可以想到几件事并将它们放在我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    相关资源
    最近更新 更多