2015-10-19 121 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填充 - 你不能带出你想要的钥匙使用。