निम्नलिखित कोड में, हालांकि सब कुछ अच्छा दिखता है लेकिन टाइपस्क्रिप्ट एक त्रुटि दिखाता है जो अजीब लगता है:

class Sample {

    private value = 1;

    private incrementValue(): void {
        this.value++; 
    }

    private beginTest(): void {

        if (this.value !== 1) {
            throw "bad state!"
        }

        this.incrementValue();

        if (this.value != 2) {
            throw "bad state!"; // ERROR!!: This condition will always return 'true' since the types '1' and '2' have no overlap.
        }
    }
}

टाइपस्क्रिप्ट को ऐसी त्रुटि क्यों उठानी चाहिए? मैं value को this.incrementValue() से बदल रहा हूं। ऐसा लगता है कि इस प्रकार की त्रुटि संकलन त्रुटि के बजाय एक IntelliSense चेतावनी से अधिक होनी चाहिए।

संभवतः यह क्रमिक प्रकार की प्रणाली के कारण है, लेकिन चूंकि यह इन स्थितियों में विफल रहता है, इसलिए इसे हल करने के लिए एक संकलन विकल्प होना चाहिए।

क्या इसे बंद करने के लिए कोई वैकल्पिक हल या विशेष संकलन विकल्प है?

5
mehrandvd 25 मई 2019, 18:07

1 उत्तर

सबसे बढ़िया उत्तर

जबकि टाइपस्क्रिप्ट का प्रकार अनुमान आमतौर पर सही प्रकार का अनुमान लगाने में बहुत अच्छा होता है, भाषा में सीमित नियंत्रण प्रवाह विश्लेषण होता है। Microsoft में टाइपस्क्रिप्ट टीम के प्रमुख डेवलपर का तर्क है:

प्राथमिक प्रश्न यह है कि: जब किसी फ़ंक्शन को लागू किया जाता है, तो हमें यह मान लेना चाहिए कि इसके दुष्प्रभाव क्या हैं?

एक विकल्प निराशावादी होना और सभी संकीर्णताओं को रीसेट करना है, यह मानते हुए कि कोई भी फ़ंक्शन किसी भी वस्तु को बदल सकता है, जिस पर वह संभवतः अपना हाथ रख सकता है। एक अन्य विकल्प आशावादी होना और यह मान लेना है कि फ़ंक्शन किसी भी स्थिति को संशोधित नहीं करता है। ये दोनों ही खराब लगते हैं।

— रयान कैवानॉघ, कंट्रोल फ्लो एनालिसिस में ट्रेड-ऑफ़

आपके उदाहरण की व्याख्या

पहले इफ-स्टेटमेंट में टाइपस्क्रिप्ट एक संख्या प्रकार के रूप में this.value का मूल्यांकन करता है।

पहले if-statement के ठीक बाद, टाइपस्क्रिप्ट यह निर्धारित करता है कि this.value अब number प्रकार का नहीं है। इसके बजाय यह शाब्दिक प्रकार 1 का है .

ऐसा इसलिए है क्योंकि 1 (!== 1) से भिन्न कोई भी मान फ़ंक्शन को समाप्त कर देता। इसलिए, कोई भी मान जो समाप्त नहीं होता है और इसके बजाय अगले if-statement पर जाता है, सटीक शाब्दिक मान 1 होना चाहिए।

जब आप this.incrementValue(); को कॉल करते हैं, तो टाइपस्क्रिप्ट को पता नहीं होता है कि फ़ंक्शन this.value की स्थिति को बदल देता है। जब तक आप दूसरे इफ स्टेटमेंट पर पहुंच जाते हैं, तब तक टाइपस्क्रिप्ट अभी भी मानता है कि this.value शाब्दिक प्रकार 1 का है।

इस वजह से, यह दूसरे इफ़-स्टेटमेंट का मूल्यांकन उसी तरह करता है जैसे यदि आपने this.value को शाब्दिक 1 से बदल दिया होता

if (1 != 2)

(यह भी ठीक वैसी ही त्रुटि देता है)

आपकी समस्या का समाधान

अभी आपकी समस्या के लिए, सबसे आसान समाधान या तो होगा:

  • टाइपस्क्रिप्ट को बताएं कि this.value एक संख्या है if ((this.value as number) != 2)
  • मान को किसी संख्या if (+this.value != 2) पर कास्ट करें
  • ऊपर की लाइन पर एक // @ts-ignore टिप्पणी जोड़ें ताकि टाइपस्क्रिप्ट कंपाइलर त्रुटि को अनदेखा कर दे

टाइपस्क्रिप्ट के नियंत्रण प्रवाह विश्लेषण में सुधार के लिए समाधान

रयान कैवानुघ ने टाइपस्क्रिप्ट के नियंत्रण प्रवाह विश्लेषण में सुधार के लिए कुछ विचारों का उल्लेख किया है:

  • pure फ़ंक्शन पर संशोधक जो कहता है कि यह फ़ंक्शन कुछ भी संशोधित नहीं करता है। यह थोड़ा अव्यावहारिक है क्योंकि हम वास्तविक रूप से इसे सभी कार्यों के विशाल बहुमत पर चाहते हैं, और यह वास्तव में समस्या का समाधान नहीं करता है क्योंकि बहुत सारे फ़ंक्शन केवल एक चीज़ को संशोधित करते हैं, इसलिए आप वास्तव में "एम को छोड़कर शुद्ध" कहना चाहेंगे "

  • volatile संपत्ति संशोधक जो यह कहता है कि "यह संपत्ति बिना किसी सूचना के बदल जाएगी"। हम C++ नहीं हैं और शायद यह स्पष्ट नहीं है कि आप इसे कहां लागू करेंगे और कहां नहीं।

3
Community 20 जून 2020, 09:12