如何将TypeScript对象转换为普通对象?

25
我正在使用一个JS库,具体来说是select2,如果我传递给它的对象不是普通对象,它会表现得有些不同。通过使用jQuery的isPlainObject函数进行检查。
TypeScript有没有我不知道的转换方式可以实现这一点,而不必编写自己的代码呢?
class Opt {
    constructor(public id, public text) {

    }

    toPlainObj(): Object {
        return {
            id: this.id,
            text: this.text
        }
    }
}

let opts = [
    new Opt(0, 'foo'),
    new Opt(1, 'bar')
];

console.clear()

console.log('both should be false')
$.map(opts, opt => {
    console.log($.isPlainObject(opt))
})

console.log('both should be true')
$.map(opts, opt => {
    console.log($.isPlainObject(opt.toPlainObj()))
})

请在此处发布您的代码 - messerbill
@messerbill 我不相信SO的代码片段支持TypeScript。至少,我无法让它工作。 - self.
将以下与编程有关的内容从英语翻译成中文。只需将翻译后的文本返回即可:在此处输入翻译后的文本 - 您不需要使用代码片段功能。 - messerbill
5个回答

40
您可以使用 Object.assign()
class Point {
    private x: number;
    private y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    getX(): number {
        return this.x;
    }

    getY(): number {
        return this.y;
    }
}

let p1 = new Point(4, 5);
let p2 = Object.assign({}, p1);

p1是类实例,而p2只是{ x: 4, y: 5 }

使用toPlainObj方法:

class Point {
    private x: number;
    private y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    getX(): number {
        return this.x;
    }

    getY(): number {
        return this.y;
    }

    toPlainObj(): { x: number, y: number } {
        return Object.assign({}, this);
    }
}

如果您需要在更多类中使用此功能,则可以创建一个具有此方法的基类:

class BaseClass<T> {
    toPlainObj(): T {
        return Object.assign({}, this);
    }
}

class Point extends BaseClass<{ x: number, y: number }> {
    private x: number;
    private y: number;

    constructor(x: number, y: number) {
        super();

        this.x = x;
        this.y = y;
    }

    getX(): number {
        return this.x;
    }

    getY(): number {
        return this.y;
    }
}

太好了!我差点就要发飙了,但是这个答案救了我一命 :) - MartinJH
我正在寻找完全相反的情况。有一个普通的js对象,想将其转换为特定类型。 - Moulde
1
@Moulde 类似于这样:https://dev59.com/DlgQ5IYBdhLWcg3wGgFY? - Nitzan Tomer
4
值得一提的是,这不会将任何对象属性转换为JS对象,它们仍将保持其原来类型的实例。请参见以下示例:https://www.typescriptlang.org/play/#code/MYGwhgzhAECC0G8C+AoFpIwEKJdaADgK4BGIAlsNAG5ggBcc0AvNAHYCmA7nABQCUAbhSoUIDgBdoADxbtu0LAOEo6HAE4Tes8mwgSwbYBwD2AM0VDoAemvQAKuqIdV4zdoB0tENF37DxuZwVrYOTi5iktAAnnIA8iQAVhzAEh6Y5ADmbLzIADQyQmhq7rF+BkamFlghdgBidBAuJVrRXnS+ehWBFrC1Yc4oQA - Qyaffer
@Qyaffer,你知道是否有任何方法可以将对象实例属性转换为普通对象吗? - mattbeiswenger

10

像这样的东西很简单并且它有效:

let plainObj;
try {
    plainObj = JSON.parse(JSON.stringify(obj));
} catch(e) {
    console.error(e)
}

对象中的日期搞错了。 - eozzy

2
你只需要解构对象。像这样:{...myObject}

0

Lodash 的内部函数是不为人知的英雄。它们默认情况下不会被导出。_baseClone 可以做到这一点。我在我的 Angular 项目中使用它。

import * as baseClone from 'lodash/_baseClone'

const classObj = getComplexClassObject();
const flatObj = baseClone(classObj, 7);

7 是因为 1 | 2 | 4。分别是 Deep Flag、Flat Flag 和 Symbols Flag。请查看 _baseClone.js


-1

我知道这是一个旧帖子,但在Nitzan上面的答案中,typescript语法检查器似乎只需要执行以下操作即可:

const plainObj:any = ClassObj;
ClassObj.newProperty = "Test";

所以看起来除非我不知道什么区别,否则没有真正需要使用Object.assign。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接