Typescript 接口 - 字段类型:MyInterface |字符串,尝试访问属性时不起作用

Posted

技术标签:

【中文标题】Typescript 接口 - 字段类型:MyInterface |字符串,尝试访问属性时不起作用【英文标题】:Typescript interface - field with type: MyInterface | string, not working when trying to access property 【发布时间】: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 设置为什么?最有可能的候选者是字符串本身,或者未定义。 【参考方案1】:

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

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

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

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

请注意,documentjavascript 中的保留字。我会使用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 属性。

【讨论】:

以上是关于Typescript 接口 - 字段类型:MyInterface |字符串,尝试访问属性时不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 接口 - 字段类型:MyInterface |字符串,尝试访问属性时不起作用

深入浅出TypeScript- 使用接口和类型别名

如何在 TypeScript 中构建自定义的必需接口?

TypeScript 如何知道自定义数组类型中长度字段的行为?

Java接口

将接口中的字段类型替换为 Promise