【问题标题】:Typescript property does not exist on union type联合类型上不存在 Typescript 属性
【发布时间】:2021-09-30 17:50:30
【问题描述】:

这是我遇到过几次的情况,看起来应该很简单,但我找不到不将类型设置为任何的解决方案

函数将两个不同对象之一作为参数,检查接收到的对象,并返回相应的字段。

这是问题的简化版本,但问题是这两个对象只能通过它们的属性(没有重叠)来区分,我无法访问任何属性,因为它们不存在在其他类型上。

type Obj1 = {
  message: string
}

type Obj2 = {
  text: string
}

const getText = (obj: Obj1 |obj2): string => {
  if (obj.message) {
    return obj.message
  }

  return obj.text
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你必须缩小类型。您可以使用in 运算符来完成此操作。

    const getText = (obj: Obj1 | Obj2): string => {
      if ("message" in obj) {
        return obj.message
      }
    
      return obj.text
    }
    

    【讨论】:

    • 这真的让我很吃惊,因为我曾尝试使用 obj.hasOwnProperty('message'),它无法编译,之后我再也不会想到使用 in 运算符了。
    • 这应该是公认的答案。使用in 将允许打字稿推断正确的变量类型,您应该避免显式转换
    • 有没有办法在模板中正确地做到这一点?
    • 如果联合类型之一是原始类型怎么办?它给出了一个错误,说您不能将in 与原语一起使用。
    • TS 可以将类型联合与此区分开来但不能使用可选链接运算符(即(obj?.message) ? ... : ...
    【解决方案2】:

    您可以将对象投射到Obj1Obj2

    type Obj1 = {
      message: string
    }
    
    type Obj2 = {
      text: string
    }
    
    const getText = (obj: Obj1 | Obj2): string => {
      if ((obj as Obj1).message) {
        return (obj as Obj1).message
      }
    
      return (obj as Obj2).text
    }
    

    【讨论】:

      【解决方案3】:

      根据楼主的提问,这个问题的真正答案是this

      但是有时您可能会以这种方式将your defined typeprimitive type 一起使用,上述解决方案无法解决我遇到的问题 情况是这样的

      type Obj1 = {
        message: string
      }
      
      const getText = (obj: Obj1 |string): string => {
        if (obj.message) {
          return obj.message
        }
      
        return obj.text
      }
      

      所以在这种情况下,上述解决方案对你来说并不完美,所以你可能需要使用typeof✌️

      const getText = (obj: Obj1 | string): string => {
        if (typeof obj !== 'string') {
          return obj.message
        }
      
        return obj.text
      }
      

      【讨论】:

        【解决方案4】:

        我推荐typescript-is

        import { is } from 'typescript-is';
        
        ...
        
        const getText = (obj: Obj1 | Obj2): string => {
          if (is<Obj1>(obj)) {
            return obj1.message;
          }
        
          return obj2.text;
        };
        

        【讨论】:

          猜你喜欢
          • 2023-01-19
          • 1970-01-01
          • 2021-02-25
          • 2020-09-27
          • 2023-04-02
          • 2018-08-17
          • 1970-01-01
          • 2023-02-06
          • 1970-01-01
          相关资源
          最近更新 更多