2015-10-19 120 views
16

與解構相結合的參數屬性速記在打字稿,當我們想自動創建在我們從構造函數定義類的屬性,我們可以利用的參數屬性的簡寫,例如:在打字稿

class Person { 
    constructor(public firstName : string, public lastName : number, public age : number) { 

    } 
} 

而且屆時,transpiled的JavaScript將是:

var Person = (function() { 
    function Person(firstName, lastName, age) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.age = age; 
    } 
    return Person; 
})(); 

但是,如果我們要接受一個對象在我們的構造,它會是這樣的:

interface IPerson { 
    firstName : string, 
    lastName : string, 
    age: number 
} 

class Person { 
    constructor(person : IPerson) { 
     this.firstName = person.firstName; 
     this.lastName = person.lastName; 
     this.age = person.age; 
    } 
} 

由於打字稿1.5,我們可以利用解構的,e.g:

class Person { 
    constructor({firstName, lastName, age} : {firstName: string, lastName: string, age: number}) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.age = age; 
    } 
} 

問題:如何打字稿參數屬性速記和解構結合起來?

我試過對象定義之前定義public,e.g:

class Person { 
    constructor(public {firstName, lastName, age} : {firstName: string, lastName: string, age: number}) { 

    } 
} 

嘗試每個變量之前定義它,e.g:

class Person { 
    constructor({public firstName, public lastName, public age} : {firstName: string, lastName: string, age: number}) { 

    } 
} 

但我沒有成功。有什麼想法嗎?

回答

3

目前還不能辦法做到這短短的手,這樣你就可以得到最接近的是手寫聲明的屬性和分配從解構賦值變量:

class Person { 
    firstName: string; 
    lastName: string; 
    age: number; 

    constructor({firstName, lastName, age} : {firstName: string, lastName: string, age: number}) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.age = age; 
    } 
} 

如果你正在做的那......你可能會決定接受一個IPerson,並且在構造函數中根本沒有使用解構分配它的成員。

1

另一種策略是使用分配給不同名稱變量的能力。這減少了構造函數中的一次重複。

class Person { 
    firstName: string; 
    lastName: string; 
    age: number; 

    constructor(args: { firstName: string, lastName: string, age: number, }) { 
     ({ 
      firstName: this.firstName, 
      lastName: this.lastName, 
      age: this.age, 
     } = args); 
    } 
} 

您還可以將構造函數中的定義之一移動到接口。

interface PersonConstructorArgs { 
    firstName: string; 
    lastName: string; 
    age: number; 
} 
class Person { 
    firstName: string; 
    lastName: string; 
    age: number; 

    constructor(args: PersonConstructorArgs) { 
     ({ 
      firstName: this.firstName, 
      lastName: this.lastName, 
      age: this.age, 
     } = args); 
    } 
} 

當你有層次結構時,這會很有用。

interface PersonConstructorArgs { 
    firstName: string; 
    lastName: string; 
    age: number; 
} 
class Person { 
    firstName: string; 
    lastName: string; 
    age: number; 

    constructor(args: PersonConstructorArgs) { 
     ({ 
      firstName: this.firstName, 
      lastName: this.lastName, 
      age: this.age, 
     } = args); 
    } 
} 
interface EmployeeConstructorArgs extends PersonConstructorArgs { 
    manager: Person; 
} 
class Employee extends Person { 
    manager: Person; 

    constructor(args: EmployeeConstructorArgs) { 
     super(args); 
     ({ 
      manager: this.manager, 
     } = args); 
    } 
} 
+0

您是否知道爲什麼需要在括號內包裝解構賦值?我的意思是'({manager:this.manager} = args)''中的外部'()'。我發現在映射到對象屬性時是必要的(如* this。管理器*),而當通過局部變量映射時通常不需要它們 – superjos

+1

[對象解構部分](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#object-解構)TypeScript手冊中寫道:「注意,我們必須用括號括住這條語句,JavaScript通常會解析{作爲塊的開始。」 所以原因是它會認爲它是一個塊而不是對象解構。 – Schmalls

1

如果你有機會獲得Object.assign,這個工程:

class PersonData { 
    firstName: string 
    constructor(args : PersonData) { 
    Object.assign(this, args) 
    } 
} 

class Person extends PersonData{} 

但需要注意的新情況將由任何在args填充 - 你不能帶出你想要的鑰匙使用。