在类的构造中,typescript destructuring object literal,默认属性不起作用

时间:2017-06-03 10:57:24

标签: angular typescript typescript2.0

我正在尝试使用默认值来解析对象文字,但我没有得到默认值,只是'undefined'。什么是正确的方法?

import { Component } from '@angular/core';
export class Hero {
  id: number;
  name: string;
 // constructor( {id = 3, name = 'defaulthero'} = {}) {
  constructor( {id  , name }: {id?: number, name?: string } = { id:3, name: 'defaulthero'} ) {
    console.log( id, name);
    this.id = id;
    this.name = name;
  }
}

@Component({
  selector: 'my-app',
  template: `<h1>{{title}}</h1><h2>Hero {{hero3.id}} {{hero3.name}}</h2>`,
})
export class AppComponent    {
  title = 'Tour of Heros';
  public hero3: Hero;


  ngOnInit() {

    //this.hero3  = new Hero (  ) ;  // work
    //this.hero3  = new Hero (  {} ) ; // does not work
    this.hero3  = new Hero ( {id: 0} ) ;  // does not work, default value 'defaulthero' not assign, just i get 'undefined'
  }
}

3 个答案:

答案 0 :(得分:2)

我发现了两个受到启发的替代解决方案:

1)解决方案类英雄: https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#improved-checking-for-destructuring-object-literal

2)解决方案类Hero2:section&#34; Optional Properties&#34; https://www.typescriptlang.org/docs/handbook/interfaces.html

import { Component, OnInit  } from '@angular/core';

interface HeroInterface { 
  // you need add ? for each variable (Optional Properties)
  id?: number;
  name?: string;

}

// Class using solution 1
class Hero {
  id: number;
  name: string;
  //without interface: constructor({id= 3, name= 'defaulthero'}: {id?: number, name?: string } = {}) {
  constructor({id= 4, name= 'Spiderman'}: HeroInterface = {}) {
    this.id = id;
    this.name = name;
  }

}

// Class solution 2 ,using short way of assign property on constructor()
class Hero2 {
  constructor(public config: HeroInterface = {}) { // short way to assign config like this.config = config; 

    if (!config.id) this.config.id =10;
    if (!config.name) this.config.name = 'SuperMan';
  }

}


@Component ( {
  selector: 'my-app',
  template: `hero1: id: {{hero.id}} name: {{hero.name}} 
            <br/>hero2: id: {{hero2.config.id}} name: {{hero2.config.name}}
    `
})
export class AppComponent implements OnInit {
  hero: Hero ;
  hero2: Hero2 ;
  ngOnInit () {

    // SOLUTION 1:  
    // this.hero = new Hero ();
    this.hero = new Hero ( { id:9 });

    // SOLUTION 2:
    this.hero2 = new Hero2 ( ); // Works with default values
    //this.hero2 = new Hero2 ( { id: 20} ); // Works with default name value
    //this.hero2 =  new Hero2 ( { id: 20, name: 'Asterix'}); // send all values, don't need use default values
    //this.hero2 = new Hero2 ( { id:19 , name: 'Asterix', weight:90}); // Error, 'weight' does not exist in type 'HeroInterface'
  }
}

答案 1 :(得分:0)

如果您没有为object fields分配默认值,则typescript会将其视为正常参数(对象类型),如下所示:

constructor(obj: any = {id:3, name: 'defaulthero'})
  • hero创建new Hero()的新实例时,constructor没有参数,因此将使用默认的{id:3, name: 'defaulthero'}

  • hero创建new Hero({})的新实例时,会有一个参数,它是一个没有字段的对象,它将被用作收入参数并取代默认{id:3, name: 'defaulthero'}。(与new Hero ( {id: 0} )相同)

由于您的代码块中有一条注释行,您可以使用以下更改为对象参数字段指定默认值:

constructor({id=3, name='defaulthero'}: {id?: number, name?: string } = {}) {
  this.id = id;
  this.name = name;
}

<强> Plunker demo

答案 2 :(得分:0)

它按预期工作,您正在为对象设置默认值,然后它会被破坏。如果用自己的对象替换该对象,则只有它的值才会填充参数。但是,这是一种存档所需行为的方法,而不是将默认值设置为对象:

  constructor({id, name }: {id?: number, name?: string } = {id:3, name: 'defaulthero'}) {
    console.log( id, name);
    this.id = id;
    this.name = name;
  }

为每个论点做一遍:

  constructor({id = 3, name = 'defaulthero'}: {id?: number, name?: string }  = {}) {
    console.log( id, name);
    this.id = id;
    this.name = name;
  }