TypeScript-以更好的方式“更新”一个类?

时间:2018-08-01 17:50:06

标签: javascript typescript ecmascript-6

我有很多像这样一直在构造的模型:

interface IPerson {
  firstName: string;
  lastName: string;
  fullName: string;
}

class Person implements IPerson {
  public firstName: string;
  public lastName: string;
  public fullName: string;
  constructor(_firstName: string, _lastName: string) {
    this.firstName = _firstName;
    this.lastName = _lastName;
    this.fullName = `${this.firstName} ${this.lastName}`;
  }
}

然后我最终调用一些api返回一些json。

示例响应:

{
    "data": [
    {
      “firstName”: “John”,
      “lastName”: “Doe”
    },
    {
      “firstName”: “Jane”,
      “lastName”: “Doe”
    }
  ]
}

收到回复后,我将通过执行以下简单操作来“更新”:

return response.data.map( d => new Person(d.firstName, d.lastName));

我的问题:

我有一些具有大量属性的模型,将它们作为参数传递并将它们绑定到各自的属性上似乎是非常多余的(至少感觉就是这样)。有更优雅的方法吗?

我看到很多与下面的示例相似的东西,但是似乎没有一个东西实际上在类中“更新”了对象,因此它的行为正确(即:串联firstName和lastName)。

类似的文章似乎提到了这样的东西:

var modal: IModal = {
    content: '',
    form: '',
    href: '',
    $form: null,
    $message: null,
    $modal: null,
    $submits: null
};

其他类似的内容:

modal: IModal = <IModal>{}

var modal = {} as IModal 

2 个答案:

答案 0 :(得分:3)

编写一个使用IPerson

的构造函数
interface IPerson {
  firstName: string;
  lastName: string;
  fullName: string;
}

class Person implements IPerson {
  public firstName: string;
  public lastName: string;
  public fullName: string;
  constructor(_firstName: string, _lastName: string) {
    this.firstName = _firstName;
    this.lastName = _lastName;
    this.fullName = `${this.firstName} ${this.lastName}`;
  }
  public static fromIPerson(person: IPerson): Person {
    return new Person(person.firstName, person.lastName);
  }
}

答案 1 :(得分:1)

您可以使用Object.assign来避免每次都列出属性,而是使用数据对象本身。 -example

更新:声明了一个过滤器函数,以从源数据中删除不属于该类的属性。但是存在一个缺点,即类属性必须具有初始值才能使其出现在已编译的javascript代码中。如果它们没有初始值,则typescript类将被编译为空,并且将无法在运行时获取typescript类的属性列表。

function filter(obj, data) {
  return Object.getOwnPropertyNames(obj).reduce((acc, k) => {
    acc[k] = data[k];
    return acc;
  }, {})
}

class Person implements IPerson {
  public firstName: string = "";
  public lastName: string = "";
  public get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
  constructor(data) {
    Object.assign(this, filter(this, data))
  }

}