联合类型上不存在 Typescript 属性

Pet*_*erN 33 typescript

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

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

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

type Obj1 = {
  message: string
}

type Obj2 = {
  text: string
}

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

  return obj.text
}
Run Code Online (Sandbox Code Playgroud)

Mur*_*göz 66

你必须缩小类型。您可以通过使用in运算符来执行此操作。

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

  return obj.text
}
Run Code Online (Sandbox Code Playgroud)

  • TS 可以区分类型联合,但不能使用可选链接运算符(即 `(obj?.message) ?)来做到这一点,这很愚蠢。...:...` (66认同)
  • 这真的让我感到惊讶,因为我曾尝试使用 obj.hasOwnProperty('message'),但它无法编译,之后我就再也没有想过使用 in 运算符。 (4认同)
  • 这应该是公认的答案。使用“in”将允许打字稿推断正确的变量类型,您应该避免显式转换 (3认同)
  • 如果联合类型之一是原始类型怎么办?它给出一个错误,指出您不能将“in”与原语一起使用。 (3认同)
  • 有什么方法可以在模板中正确执行此操作吗? (2认同)

Nse*_*ens 13

您可以将对象强制转换为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
}
Run Code Online (Sandbox Code Playgroud)


Ntw*_*ste 6

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

\n

但有时您可能会your defined typeprimitive type这种方式使用上述解决方案,因为我面临的问题\n情况如下

\n
type Obj1 = {\n  message: string\n}\n\nconst getText = (obj: Obj1 |string): string => {\n  if (obj.message) {\n    return obj.message\n  }\n\n  return obj.text\n}\n
Run Code Online (Sandbox Code Playgroud)\n

因此,在这种情况下,上述解决方案并不适合您,因此您可能需要使用typeof\xe2\x9c\x8c\xef\xb8\x8f

\n
const getText = (obj: Obj1 | string): string => {\n  if (typeof obj !== \'string\') {\n    return obj.message\n  }\n\n  return obj.text\n}\n
Run Code Online (Sandbox Code Playgroud)\n