【问题标题】:Typescript: property does not exist on combined type?打字稿:组合类型上不存在属性?
【发布时间】:2020-05-21 13:12:37
【问题描述】:

以下抽象的 TS 场景:

interface EmotionsOkay {
  emotion: string;
  okay: "yap";
}
interface EmotionsNotOkay {
  emotion: string;
}
type UndetereminedEmotion = EmotionsOkay | EmotionsNotOkay;
const areYouOkay = (test: UndetereminedEmotion) => {
  console.log(test.okay ? "happy :D" : "sad D:");
};

在控制台记录 test.okay 时抛出 TypeScript 错误,因为它显然不存在。

Property `okay` does not exist on type `UndetereminedEmotion`.

即使它很可能存在,但如果传递给方法的测试是EmotionsOkay 类型。

为什么会这样?

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    此时,TS 不知道它是什么类型,可能是EmotionsOkay,一切都会好起来的,也可能是EmotionsNotOkay,而属性okay 不存在。这就是您收到此错误的原因。您需要验证它是哪种类型。

    您可以使用in 关键字来验证这一点,

    interface EmotionsOkay {
      emotion: string;
      okay: "yap";
    }
    interface EmotionsNotOkay {
      emotion: string;
    }
    type UndetereminedEmotion = EmotionsOkay | EmotionsNotOkay;
    const areYouOkay = (test: UndetereminedEmotion) => {
      console.log('okay' in test && test.okay ? "happy :D" : "sad D:");
    };
    

    如果你一开始就没有okay 的属性,你就不会快乐。

    如果您想知道为什么在这种情况下不能使用instanceof,请查看this question

    Here is a playground

    【讨论】:

    • 嗯,我现在有点明白了,并且能够用这个修复我的用例。但是为什么围绕它的条件检查/ if 语句不能解决问题呢?为什么必须使用 TS 语法而不是通常的 JS if 语句?
    • 我不确定我是否理解您将if 放在哪里,但如果它在areYouOkay 回调中,应该没问题,只要您验证您的test 变量实现@ 987654334@ 在检查它的okay 属性之前,你应该没问题。
    • 对不起,解释不好,但我的意思是当你用if (test.okay) 包装它或使用可选链接时。 typescript 不应该像使用 in 语法一样了解吗?
    • 这是个好问题,我想我没有答案。对不起。 @josias
    【解决方案2】:

    您可以使用Typescript type assertion(就像其他语言的投射一样)。

    interface EmotionsOkay {
      emotion: string;
      okay: "yap";
    }
    interface EmotionsNotOkay {
      emotion: string;
    }
    type UndetereminedEmotion = EmotionsOkay | EmotionsNotOkay;
    const areYouOkay = (test: UndetereminedEmotion) => {
      console.log((test as EmotionsOkay).okay ? "happy :D" : "sad D:");
      // or
      console.log((<EmotionsOkay>test).okay ? "happy :D" : "sad D:");
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-02
      • 2021-09-07
      • 2017-08-07
      • 2017-03-26
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多