2016-03-24 8 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; 
    } 
} 

हालांकि इस एक संकलन त्रुटि निकलेगा जबको {} बताए: - एक ही वस्तु पर गुण स्थापित करने के लिए पहले, एक खाली वस्तु को संपत्ति प्रारंभ करने में अधिमानतः निर्माता में है, क्योंकि Name इंटरफ़ेस कोfirst और ऑब्जेक्ट पर last संपत्ति की उपस्थिति की आवश्यकता है। इस त्रुटि को दूर करने, एक एक इंटरफेस पर परिभाषित करने वैकल्पिक गुण का सहारा हो सकता है:

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

तेज प्रतिक्रिया के लिए धन्यवाद, लेकिन इसके साथ समस्या यह है कि मेरे पास एक बहुत बड़ी वस्तु है और इसे इस तरह से करने से इसे आसानी से पठनीय नहीं किया जाता है जब यह केवल दो होता है। कोई सुझाव? –

+0

यह बहुत अच्छा है, लेकिन जब आपके पास एक एकल स्तर ऑब्जेक्ट होता है तो यह ठीक काम करेगा, लेकिन जब ऑब्जेक्ट 'var info = {name: {first: "someName" की तरह गहरा होता है, अंतिम: "someLastName"}}' मुझे चाहिए 'info.name = {} 'जैसे प्रत्येक स्तर को init करने के लिए और फिर' पहले' और 'अंतिम' –

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

असाइन करें वास्तव में यह करने का एक अच्छा तरीका है, धन्यवाद –

संबंधित मुद्दे