2016-03-24 7 views
7

Ich versuche first eine die Unter Eigenschaft festlegen, die in der Name Schnittstelle definiert, aber wenn Sie so einen Fehler habe ich immer zum Beispiel:In Typoskript, wie kann nicht eingestellt Eigenschaft beheben ‚ersten‘ undefinierter

interface Name{ 
    first: string, 
    last:string, 
} 

class Person{ 

    private name:Name 

    public setName(firstName, lastName){ 
     this.name.first = firstName; 
     this.name.last = lastName; 
    } 

} 


var person1 = new Person(); 
person1.setName('Tracy','Herrera'); 

Wenn ich zum laufen bringe die Fehler: Cannot set property 'first' of undefined

Jeder habe eine Idee, diese zu trainieren?

Antwort

14

Klasseneigenschaften werden nicht automatisch auf Instanziierung initialisiert. Sie müssen sie mit den entsprechenden Objekten manuell initialisieren - in diesem Fall mit einem Objekt die Eigenschaften enthält, die durch seine Schnittstelle definiert:

class Person { 
    private name: Name; 

    public setName(firstName, lastName) { 
     this.name = { 
      first: firstName, 
      last: lastName 
     }; 
    } 
} 

Ein anderer Ansatz - zum Beispiel für den Fall, gibt es mehrere Methoden Eigenschaften auf demselben Objekt Einstellung - ist, zuerst die Eigenschaft auf ein leeres Objekt zu initialisieren, vorzugsweise im Konstruktor:

class Person { 
    private name: Name; 

    constructor() { 
     this.name = {}; 
    } 

    public setName(firstName, lastName) { 
     this.name.first = firstName; 
     this.name.last = lastName; 
    } 

    public setFirstName(firstName) { 
     this.name.first = firstName; 
    } 
} 

jedoch mit dem aktuellen Setup dieses einen Compiler-Fehler ergeben, wenn {} zuZuweisen, weil die Name Schnittstelle erfordert das Vorhandensein einer first und last Eigenschaft auf dem Objekt. Um diesen Fehler zu überwinden, könnte man zu definieren optional Eigenschaften auf einer Schnittstelle zurückgreifen:

interface Name { 
    first?: string; 
    last?: string; 
} 
+0

Danke für die schnelle Antwort, aber das Problem damit ist, dass ich ein sehr riesiges Objekt habe und es so mache, dass es nicht lesbar ist, es ist einfach, wenn es nur zwei sind. irgendwelche Vorschläge? –

+0

das ist großartig, aber das wird gut funktionieren, wenn Sie ein einzelnes Level-Objekt haben, aber wenn das Objekt so tief ist wie 'var info = {name: {first:" someName ", last:" someLastName "}} Ich brauche um jedes Level wie 'info.name = {}' zu initalisieren und dann 'first' und' last' zuzuweisen. –

4

Sie müssen Namen auf ein Objekt vom Typ Namen (das heißt eine Form, die zusammenpassende Schnittstelle) einzustellen.

Zum Beispiel:

this.name = { 
    first: 'John', 
    last: 'Doe' 
} 
+1

Danke das war hilfreich –

+0

Großartig, fühlen Sie sich frei, als Antwort zu markieren. :) –

2

, wenn Sie die Freiheit haben wollen, um Änderungen vorzunehmen, separat können Sie etwas tun, wie, mit ?,

interface Name{ 
    first?: string; 
    last? : string; 
} 

class Person{ 

    private name:Name 

     public setName(firstName: string, lastName: string){ 
      this.name = { first: firstName, last: lastName }; 
     } 

     public setNameSample(firstName: string){ 
      this.name = { first: firstName }; 
     } 

     public setNameSample1(lastName: string){ 
      this.name = { last: lastName }; 
     } 
} 

im obigen Fall, wenn Sie nicht ? verwenden Sie so etwas wie in setNameSample zum Beispiel erhalten würden, wenn Sie setzen müssen nur first:

Type '{ first: any; }' is not assignable to type 'Name'. Property 'last' is missing in

Hinweis: Ich denke, die vorherige Antwort ist der Weg zu gehen, das ist nur ein zusätzlicher.

+1

Eigentlich ist das ein guter Weg, es zu tun, danke –

Verwandte Themen