带方法的对象的Typescript spead运算符

时间:2018-07-30 09:52:53

标签: angular typescript typescript2.0

在我的角度项目中,我有一个包含类型和状态字段的对象。状态可能因类型而异。有人可能会说这是不好的设计,但是目前就是这样。关键是我似乎无法在该对象上使用传播运算符,因为编译器说Property 'getStatusList' is missing in type ...

我简化了该类,但它看起来像这样:

export class Foo {
    constructor(
        public type: number,
        public status: number
    ) { }

    getStatusList(): string[] {
        switch (this.type) {
            case 3: {
                return ['Off', 'Interval', 'On Hold']
            }

            default: {
                return ['Off', 'On']
            }
        }
    }
}

这是与打字稿2.9.2和角度cli 6.1.1一起

下面的代码将触发错误,但是在打字稿游乐场编写示例代码时,我发现也许应该使用Object.assign。尽管我仍然认为我可以使用散布运算符简单地否决对象的某些属性?

const oldFoo: Foo = new Foo(3, 5);
console.log('old status: ', oldFoo.status);

const newFoo: Foo = { ...oldFoo, type: 1, status: 7 };
console.log('new status: ', newFoo.status);

1 个答案:

答案 0 :(得分:1)

使用the spread operator in object literals时,不会获得与原始对象相同类别的对象。从文档中:

  

[spread运算符]将自己的可枚举属性从提供的对象复制到新对象。

     

使用比Object.assign()短的语法,现在可以进行浅克隆(不包括原型)或合并对象。

因此,您只是“浅克隆” oldFoo。您会错过原型上的任何内容,例如方法。如果您想拥有一个实际的Foo对象,则可能应该构造一个。构造好之后,您可以使用Object.assign()一次设置多个属性,但是无论如何,如果我使用的是构造函数,我想您应该首先将正确的参数传递给构造函数。


可以改为复制原型:

const newFoo  = { ...oldFoo, type: 1, status: 7 } as Foo;
Object.setPrototypeOf(newFoo, Object.getPrototypeOf(oldFoo));

这可能会起作用,但是弄乱原型并不是我会轻易做的。


希望有帮助。祝你好运!