2015-10-19 12 views
16

a macchina, quando vogliamo creare automaticamente le proprietà della nostra classe dalla definizione del costruttore, siamo in grado di sfruttare la stenografia Proprietà parametro, ad esempio:Combinando la stenografia Proprietà parametro con destrutturazione a macchina

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

    } 
} 

E poi, il Javascript transpiled sarà:

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

Ma se vogliamo ricevere un oggetto nel costruttore, sarebbe qualcosa di simile:

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; 
    } 
} 

Dal tipografico 1.5, siamo in grado di usufruire di destrutturazione, per esempio:

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

Domanda: come coniugare la stenografia Proprietà parametro e destrutturazione a macchina?

ho cercato di definire public prima della definizione dell'oggetto, per esempio:

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

    } 
} 

cercato di definire prima di ogni variabile, per esempio:

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

    } 
} 

Ma non ho avuto successo. qualche idea?

risposta

3

Non c'è attualmente un modo per fare questo breve a mano, in modo che il più vicino si può ottenere è di dichiarare le proprietà longhand e assegnare le variabili derivanti dalla cessione destrutturazione:

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; 
    } 
} 

Se si sta facendo che ... probabilmente deciderete di accettare uno IPerson e assegnare i suoi membri senza usare la destrutturazione nel costruttore.

1

Un'altra strategia consiste nell'utilizzare la possibilità di assegnare a una variabile di un nome diverso. Questo riduce una ripetizione nel costruttore.

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); 
    } 
} 

È anche possibile spostare una delle definizioni nel costruttore su un'interfaccia.

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); 
    } 
} 

Questo sarà utile quando si dispone di una gerarchia.

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

Sai perché è necessario avvolgere l'incarico destrutturante tra parentesi? Intendo per es. l'esterno '()' in '({manager: this.manager} = args);'. Ho trovato che sia necessario quando si esegue il mapping sulle proprietà dell'oggetto (come * questo.manager *), mentre di solito non sono necessari quando si esegue il mapping su variabili locali – superjos

+1

C'è una nota nella sezione [Object Destructuring] (https://www.typescriptlang.org/docs/handbook/variable-declarations.html#object- destrutturazione) del manuale di TypeScript che dice "Notate che dovevamo circondare questa frase con parentesi.Il JavaScript normalmente analizza un {come l'inizio del blocco". Quindi la ragione è che penserebbe che fosse un blocco invece di un oggetto destrutturante. – Schmalls

1

Se si ha accesso a Object.assign, questo funziona:

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

class Person extends PersonData{} 

Ma notate nuove istanze sarà popolato da nulla in args - non si può striscia fuori solo i tasti che si desidera usare.