如何在TypeScript中通过指定每个属性及其值来实例化一个对象?

24

以下是我在服务中实例化新的content对象的代码片段:

const newContent = new Content(
     result.obj.name
     result.obj.user.firstName,
     result.obj._id,
     result.obj.user._id,
);

问题在于这种对象实例化方式依赖于我content模型中属性的顺序。我想知道是否有一种方法可以通过将每个属性映射到我要设置的值来完成,例如:

问题是该对象实例化方式取决于content模型中属性的顺序。请问是否有一种方法可以通过将每个属性映射到要设置的值来解决这个问题,例如:

 const newContent = new Content(
     name: result.obj.name,
     user: result.obj.user.
     content_id: result.obj._id,
     user_id: result.obj.user._id,
 );
3个回答

24

1
你改了什么很清楚,但说一下为什么会更有帮助。教育时刻无处不在。 - Anthony Horne
30
这其实非常非常错误!你在这里没有实例化 Content 类的一个实例,而是创建了一个具有相同成员的简单对象。例如,如果 Content 类有一个名为 fn 的方法,在你的示例中调用 newContent.fn() 将会失败。 - Nitzan Tomer
2
如果你像下面这样扩展对象的原型,那么这个答案就可以工作: const newContent = <Content>(_.extend({...}, Content.prototype)); - logeyg
如前所述,这仅适用于接口,这也是我使用它的原因。 - shturm

13
您可以将一个对象传递给构造函数,该对象包装了所有这些变量:
type ContentData = {
    name: string;
    user: string;
    content_id: string;
    user_id: string;
}

class Content {
    constructor(data: ContentData) {
        ...
    }
}

然后:

const newContent = new Content({
     name: result.obj.name,
     user: result.obj.user.
     content_id: result.obj._id,
     user_id: result.obj.user._id,
});

1
从一个C#背景出发,我们都习以为常地使用对象初始化器,我也想看看在TypeScript中是否能够实现类似的语法来初始化数据字段,而不需要太多的重复代码/样板文件。以下是我想出来的代码:
type FunctionProp<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
type Fields<T> = Omit<T, FunctionProp<T>>;
type PartialFields<T> = Partial<Fields<T>>;

class User {}
class Content {
    public name!: string;
    public user!: User; 
    public content_id!: string; 
    public user_id!: string;

    constructor(obj: Fields<Content>) { 
        for (const key of Object.keys(obj)) {
            (this as any)[key] = (obj as any)[key];
        }
    }

    print() { console.log(this.name); }
}

const content = new Content({
    name: "test",
    user: new User(),
    user_id: "USER-001",
    content_id: "CONTENT-001"
});
console.log(content);
// Output: Content {name: 'test', user: User, content_id: 'CONTENT-001', user_id: 'USER-001'}

在我看来,这使得初始化简单数据对象(DTOs,POCOs)更易读,减少了错误的可能性。在构造函数中,可以使用PartialFields<Content>代替Fields<Content>,以适应初始化器中的可选属性。


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