在打字稿中使用联合类型时属性不存在

时间:2020-02-03 22:47:30

标签: typescript union-types

假设我有两个接口:

interface Box {
    x: number
    y: number
}

interface ColouredBox {
    x: number
    y: number
    colour: string
}

出于这个问题的目的,我不能更改接口。

现在构造对象时,我有这样的代码:

let a: Box|ColouredBox = {x: 1, y: 2}
if( something ){
    a.colour = "Blue"  // Compilation Error
}

我在a.colour = "Blue"上收到此错误:

Error:(24, 26) TS2339: Property 'colour' does not exist on type 'Box'.

为什么?这是TS编译器的限制吗?除了完全重建对象之外,还有其他可以使用的工作流程吗?

2 个答案:

答案 0 :(得分:1)

您可以使用in type guard

if ("colour" in a) {
    a.colour = "Blue"  // works
}

基于属性ColouredBox的存在,这将缩小为联合部分colour。通常,如果之前没有缩小范围,则只能选择x的所有公用属性y / Box | ColouredBox

Live code sample here

答案 1 :(得分:1)

使用部分

您可以尝试使用Partial

来代替使用联合类型
let a: Partial<ColouredBox> = {x: 1, y: 2}

该局部对象会将ColoredBox的所有属性设置为可选。

实时示例here

更新

消除界面

如果只希望界面的颜色部分是可选的,则可以消除其中一个界面。

interface Box {
  x: number;
  y: number;
  color?: string;
}

然后确定是否要处理彩色框:

if (box.color) { ... }

类型声明

如果您坚持使用两个界面,则可以使用a关键字(也称为类型声明)将ColouredBox视为as

let a: Box | ColouredBox = { x: 1, y: 2 };
(a as ColouredBox).colour = "Blue";