2016-03-24 1 views
7

Я пытаюсь установить суб свойства first, который определен в интерфейсе Name но когда делать, так что я всегда получаю сообщение об ошибке, например:В машинописи, как исправить не удается установить свойство «первый» неопределенной

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

При запуске его я получаю сообщение об ошибке: Cannot set property 'first' of undefined

Любой есть идея, чтобы решить эту проблему?

ответ

14

Свойства класса не будут автоматически инициализируется на конкретизации. Вы должны инициализировать их с соответствующими объектами вручную - в этом случае с объектом, содержащим свойства, определяемые его интерфейса:

class Person { 
    private name: Name; 

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

Другой подход - например, в случае, если существует несколько методов установки свойств на тот же объект - это сначала инициализировать свойство пустого объекта, предпочтительно в конструкторе:

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

Однако при текущей настройке это даст ошибку компиляции при назначении {} к this.name, поскольку для интерфейса Nameтребуется наличие first и имущества last на объекте. Чтобы преодолеть эту ошибку, можно прибегнуть к определению дополнительных свойств на интерфейсе:

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

Спасибо за быстрый ответ, но проблема в том, что у меня есть очень огромный объект, и поэтому он делает его непригодным для чтения, когда его просто два. какие-либо предложения? –

+0

Это замечательно, но это будет отлично работать, если у вас есть объект одного уровня, но когда объект настолько глубок, как «var info = {name: {first:" someName ", last:" someLastName "}}' Мне нужно чтобы инициализировать каждый уровень, например 'info.name = {}', а затем назначить 'first' и' last' –

4

Вам нужно установить имя к объекту типа Название (то есть в форме, соответствующей этот интерфейс).

Например:

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

Спасибо, что было полезно –

+0

Отлично, не стесняйтесь пометить как ответ. :) –

2

, если вы хотите иметь свободу, чтобы внести изменения, отдельно вы можете сделать что-то подобное, используя ?,

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

в приведенном выше случае, если вы не используете ? вы получите что-то вроде в setNameSample, например, если вам нужно установить только first:

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

Примечание: Я думаю, что предыдущий ответ - путь, это просто добавленный.

+1

На самом деле это хороший способ сделать это, спасибо –

Смежные вопросы