angular - האם יש דרך לקבל את סוג המוצהר של מאפיין במקום את סוג הערך שהוקצה ב-Typescript


אני מנסה ליצור מחלקת מודל גנרית ב-TypeScript שניתן להרחיב על ידי מודלים ילדים לצורך יצירת שיטת עיבוד אוטומטית של נתוני HTTP למודל במחלקה העליונה.

מודל ילד בסיסי עשוי להיות כזה:

export class User extends Model {

    private username: string = null;

    constructor () {
        super ();
        this.processJson ();
    }
}

עם המחלקה האב שלנו Model שעושה משהו כזה:

export class Model {

    constructor () {
    }

    public processJson<T> () {

        _.forEach (Object.keys (this), (key: string) => {
            console.log (`processing key: ${key}`);
            console.log (typeof this[key]);
        })
   }
}

התוכנית היא להשתמש בשיטה processJson כנקודת כניסה יחידה כדי לקחת נתוני JSON נכנסים ולעבד אותם למודלים הילדיים שלנו בהתאם להגדרתם.

הבעיה כאן היא שאני לא מצליח לקבל את סוג המשתנה שהוגדר במודל הילד, בדוגמה שסופקה ה-typeof this[key] יחזיר object מכיוון שהוא מסיק את סוג הערך שהוקצה, בדוגמה הזו null.

התוכנית שלי היא להשתמש בזה למקרים מורכבים יותר שבהם ייתכן שיהיו לנו אובייקטים מורכבים יותר או סוגים שונים שדורשים עיבוד מיוחד ולבצע את הכל במקום מרכזי בתוך מחלקת האב שלנו Model.

השאלה שלי היא כזאת, איך אני יכול, בידיעת התכונות של מודל הילד, לקבל את סוג המוצהר של הדוגמה שלנו ל-username כ-string ולא כ-object?

האם זהו מגבלה של ה-JavaScript הבסיסי שנוצר? או שאני מבין לא נכון איך נכסים של מחלקה שהוצהרו פועלים ב-TypeScript?

אני יודע שכאשר מכריזים על נכס כ:

private username: string = '';

זה יתן לי את הסוג הנכון, אבל אני לא רוצה לאתחל ערכים עד שהם מוקצים על ידי נתוני ה-JSON כי במקרים מסוימים null עשוי להיות ערך תקף.

תשובה #1

קוד הקטע שלך מניח שאתה צריך את המידע על סוגי TypeScript בזמן ריצה. עם זאת, בזמן ריצה כל הסוגים נמחקים על ידי קומפיילר TypeScript. הוא מפיק רק JavaScript רגיל ללא הערות סוג.

אני מאמין שהאפשרות הטובה ביותר שלך תהיה ליצור דקורטור ולקשט איתו כל משתנה במודל - ככה:

class User extends Model {
  @ModelField private username: string;
}

ודא גם שאתה מפעיל את אפשרות הקומפיילר emitDecoratorMetadata (https://www.typescriptlang.org/docs/handbook/decorators.html#metadata)

זה אמור לאפשר לך לקרוא את סוג הנכס המעוטר דרך reflect-metadata (למשל כפי שהוצע בתשובה זו: כיצד לקבל נתוני סוג במעטר של TypeScript?).

תשובה #2

ניתן לבדוק את סוג הנתון המוצהר בעזרת typeof, השוואה קשיחה === ו-instanceof

הכנס תיאור תמונה כאן