【问题标题】:Typescript interface - field with type: MyInterface | string, not working when trying to access propertyTypescript 接口 - 字段类型:MyInterface |字符串,尝试访问属性时不起作用
【发布时间】:2021-04-29 10:19:21
【问题描述】:

我正在尝试在我的 Angular 应用程序上重新创建我的猫鼬对象,因此我正在尝试制作接口。 问题是我并不总是发送带有填充字段的对象,所以我有这样的东西:

export interface Action {
  _id: string
  document: Document | string,
}
export interface Document {
  _id: string
  ...otherFields
}

在我的代码中,我有类似的东西:

const data = {
  documentId: action.document?._id
}

但我收到了阻止编译的错误:

Property '_id' does not exist on type 'string'.

那么,如何让它同时适用于这两种类型呢?

【问题讨论】:

  • 如果是字符串,你想让它做什么?
  • @NicholasTower 两个接口都来自 mongoDB,document 是 action 对象中的引用。所以如果我做人口,文档是一个对象,但如果不是,它是一个字符串
  • 我的意思是,如果action.document 是一个字符串,您希望将data.documentId 设置为什么?最有可能的候选者是字符串本身,或者未定义。

标签: angular typescript mongoose types interface


【解决方案1】:

使用type unions 时,您必须强制转换复杂类型才能使用它们的属性:

const data = {
  documentId: (action.document as Document)?._id
}

如果您想在Action 的界面中为文档存储string,我将创建一个额外的可选属性以使您不必强制转换document。:

export interface Action {
  document?: Document,
  docString?: string
}

请注意,document 是 javascript 中的保留字。我会使用doc 或其他东西。

【讨论】:

  • 如果action.document 永远不能为空或未定义,那么?. 的目的是什么?
  • 它们可以为空,但不能未定义
【解决方案2】:

我不确定这是否是处理它的最佳方法,但由于您使用的是联合类型,因此您可以在设置文档 ID 之前进行 if 检查:

if(typeof(action.document !== 'string')) {
   const data = {     
     documentId: action.document?._id
   }  
}

假装当它是一个字符串时它没有得到正确的值。

【讨论】:

  • 这段代码是无效的JS/TS。你不能以这种方式在对象字面量中编写if 语句。
  • 是的,感谢提醒,我已经编辑了它,我想现在它可以工作了
【解决方案3】:

由于action.document 可能是多个不兼容的类型,您需要添加一些代码来检查类型。假设你想使用 string 的字符串,那么可以这样做:

const data = {
  documentId: typeof action.document === 'string' ? action.document : action.document._id
}

在该三元表达式的第二部分,typescript 知道文档不能再是string,并且通过消除过程它知道它必须是Document。因此,它将允许您访问._id 属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-01
    • 2018-07-14
    • 2019-08-19
    • 2018-12-13
    • 2021-12-18
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多