Typescript-设置类成员的默认值

jos*_*ler 6 typescript angular

我有一个简单的模型:

export class Profile extends ServerData {
  name: string;
  email: string;
  age: number;
}
Run Code Online (Sandbox Code Playgroud)

当我打电话到服务器(Angular 4,$ http)时,我通常会收到以下响应:

{
  name: string;
  email: string;
}
Run Code Online (Sandbox Code Playgroud)

age属性丢失。

有什么方法可以使用我的模型并创建默认年龄,以防丢失?如果可能,我希望不必创建2个单独的模型。

我不想将年龄创建为可选属性-我需要它,即使它的默认值不正确也是如此。

更新:

这是我对服务器的呼叫:

results-manager.component.ts:

this.resultsManagerService.getResults(this.config.request.action, this.pagingAndSorting, this.args).subscribe(
  results => {
    this.results = this.results.concat(results as Profile[]);
Run Code Online (Sandbox Code Playgroud)

results-manager.service.ts:

getResults(action: string, pagingAndSorting: PagingAndSorting, args: string[]): Observable<Profile[]> {
return this.apiService.callServer(
  pagingAndSorting,
  action,
  ...args );
Run Code Online (Sandbox Code Playgroud)

}

该请求有效并且我收到了响应,但是即使我定义了默认值(如@msanford的答案所建议),当我在组件中收到响应时,它们也会被删除。同样,如果我向模型添加构造函数(根据董建华的回答)。

后端响应似乎完全覆盖了模型-不仅仅是分配值。

我如何才能仅将值分配给模型而不删除不返回的值?

gaw*_*cks 15

您看到覆盖属性的原因是TypeScript 中的类型擦除。TypeScript 不知道在运行时将什么类型的对象分配给它的变量。如果您不是来自 java/c# 背景,这对您来说似乎有些奇怪。

因为最终,它只是 JavaScript。并且 JavaScript 不强制执行严格的类型检查。

为了确保您的个人资料对象始终具有年龄属性,您可以创建自己的对象,然后复制从响应中获得的值。当涉及到域对象映射的有线格式时,这是通常的方法。

为此,首先创建您的域模型,在本例中为具有默认年龄属性的 Profile 类。

 export class Profile {
        constructor(
            public name: string,
            public email: string,
            public age: number = 0) { }
    }
Run Code Online (Sandbox Code Playgroud)

然后将您的响应映​​射到域模型。

this.resultsManagerService.getResults(this.config.request.action, this.pagingAndSorting, this.args).subscribe(
  results => {
    let res = (results as Profile[]).map((profile) => new Profile(profile.name, profile.email, profile.age));
    this.results = this.results.concat(res);
 });
Run Code Online (Sandbox Code Playgroud)


msa*_*ord 8

是的,很容易,并且您不需要添加类构造函数。

export class Profile extends ServerData {
  name: string;
  email: string;
  age: number = 0;
}
Run Code Online (Sandbox Code Playgroud)

定义默认值的能力是区别于一个主要的事情之一class从一个interface

为此,您需要new Profile()在代码中的某个地方调用,否则将不会创建类实例,也不会设置默认值,因为上述TypeScript将编译为以下JavaScript:

var Profile = /** @class */ (function () {
    function Profile() {
        this.age = 0;
    }
    return Profile;
}());
Run Code Online (Sandbox Code Playgroud)

因此,仅在编译时将其用于类型声明就不足以在运行时设置默认值。

TypeScript Playground中查看它的运行情况。