Node.js प्रोजेक्ट पर काम करना और टाइपस्क्रिप्ट का उपयोग करना।

मैं एक फ़ंक्शन तर्क प्रकार को एक विशिष्ट आधार वर्ग तक सीमित करने का प्रयास कर रहा हूं। मैं नोड और टाइपस्क्रिप्ट दोनों के साथ नया हूं और सी # पृष्ठभूमि से आया हूं, इसलिए संभवतः लैंग की कुछ विशेषताओं को समझ नहीं पा रहा हूं।

इन अंशों को लें।

सबसे पहले, मेरी कक्षा घोषणाएँ

class DTO{
}

class userDTO extends DTO{
    @IsDefined({message:"Username required"})
    @Expose()
    @Length(1,10, {message:"min 1 max 10"})
    username:String;    
  }
  
class badDTO {
    name:String;
}

अब मैं उदाहरण बनाऊंगा:

let user = new userDTO();
user.username = "My username";

let isUserDTO = user instanceof DTO; // Evaluates true

let bad = new badDTO();
bad.name = "Bob";

let isBadDTO = user instanceof DTO; // Evaluates false

यहाँ उस विधि का हस्ताक्षर है जिसे मैं कॉल करना चाहता हूँ

export default function ValidateDTO(objToValidate:DTO, validateMissingProperties:boolean): Array<string>{
    return [];
}

अंत में, जब मैं वास्तव में फ़ंक्शन को कॉल करता हूं।

let userErrors = ValidateDTO(user, true);

// Why is this allowed?
let badErr = ValidateDTO(bad, true);

मैं उम्मीद कर रहा हूं कि दूसरा ValidateDTO मुझे एक चेतावनी दिखाएगा और वास्तव में नहीं चलेगा क्योंकि 'खराब' एक डीटीओ नहीं है जैसा कि ऊपर से सिद्ध किया गया है - अगर मैं दूसरे तर्क के रूप में एक स्ट्रिंग को पारित करने का प्रयास करता हूं तो मुझे एक त्रुटि दिखाई देती है, जिसकी मुझे उम्मीद थी एक गैर-डीटीओ को पहले तर्क के रूप में पास करना।

क्या कोई कृपया मुझे दिखा सकता है कि मैं कहाँ गलत हो रहा हूँ? मैं किसी फ़ंक्शन में पारित ऑब्जेक्ट के प्रकार को कैसे प्रतिबंधित कर सकता हूं।

आवश्यकतानुसार अन्य कोड भी साझा करने में खुशी हुई। मुझे यकीन नहीं है कि मुझे और क्या याद आ रहा है।

1
Darren Wainwright 28 अक्टूबर 2020, 19:30

1 उत्तर

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

इससे आप बिल्कुल भी हैरान नहीं हैं। :-) टाइपस्क्रिप्ट टाइप सिस्टम के बारे में एक महत्वपूर्ण बात यह है कि यह स्ट्रक्चरल है, न कि नॉमिनेटिव। जब तक किसी चीज में न्यूनतम आवश्यक संरचना होती है, तब तक वह मेल खाता है, भले ही उसका वंश अलग हो। इसका मतलब है कि कोई भी ऑब्जेक्ट टाइप सिस्टम द्वारा आपके DTO प्रकार के रूप में स्वीकार किया जाएगा क्योंकि आपके DTO प्रकार में कोई गुण नहीं है, इसलिए सभी ऑब्जेक्ट इससे मेल खाते हैं।

यह अधिकतर एक सुविधा है, लेकिन कभी-कभी आप इसे अक्षम करना चाहते हैं। जब आप इसे अक्षम करना चाहते हैं तो सामान्य तरीका ब्रांडिंग संपत्ति का उपयोग करना है:

class DTO {
    __brand = "DTO" as const;
}

अब, केवल उन वस्तुओं की अनुमति दी जाएगी जिनके पास __brand मूल्य "DTO" के साथ संपत्ति है, जहां DTO ऑब्जेक्ट टाइप सिस्टम द्वारा अपेक्षित हैं।


जावास्क्रिप्ट/टाइपस्क्रिप्ट नामकरण परंपराओं को ध्यान में रखते हुए और प्रश्न कोड में गायब कुछ बिट्स की आपूर्ति करने के लिए कुछ मामूली बदलावों के साथ यहां एक पूर्ण उदाहरण दिया गया है (संभवतः इसे छोटा रखने के लिए! :-)):

class DTO {
    __brand = "DTO" as const;
}

class UserDTO extends DTO {
    /* Commenting these out as they're not relevant to the question.
    @IsDefined({message:"Username required"})
    @Expose()
    @Length(1,10, {message:"min 1 max 10"})
    */
    username: string;
    
    constructor(username: string) {
        super();
        this.username = username;
    }
}
  
class BadDTO {
    name: string = "";
}

function validateDTO(objToValidate: DTO, validateMissingProperties: boolean): string[] {
    return [];
}

// Okay
validateDTO(new UserDTO("Joe"), true);

// Disallowed by the type system
validateDTO(new BadDTO(), false);

खेल का मैदान लिंक


साइड नोट 2: उस उदाहरण में मैंने UserDTO में एक कंस्ट्रक्टर जोड़ा जिसने username प्रॉपर्टी को इनिशियलाइज़ किया। जब आप किसी इंस्टेंस प्रॉपर्टी को इनिशियलाइज़ करने के लिए कंस्ट्रक्टर पैरामीटर का उपयोग करना चाहते हैं, तो टाइपस्क्रिप्ट का एक शॉर्टहैंड है, यह मेरे उदाहरण में कार्यात्मक रूप से UserDTO के समान है:

class UserDTO extends DTO {
    /* Commenting these out as they're not relevant to the question.
    @IsDefined({message:"Username required"})
    @Expose()
    @Length(1,10, {message:"min 1 max 10"})
    */
    //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− note no `username` declaration here
    
    constructor(public username: string) {
    //          ^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− note adding `public`
        super();
        // −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− note no code here to do the
        // initialization; it's implicit in the `public` declaration above
    }
}

आप जो उपयोग करते हैं वह शैली का मामला है।

2
T.J. Crowder 28 अक्टूबर 2020, 20:01