How to parse a JSON object to a TypeScript Object

后端 未结 8 656
谎友^
谎友^ 2020-11-30 05:21

I am currently trying to convert my received JSON Object into a TypeScript class with the same attributes and I cannot get it to work. What am I doing wrong?

相关标签:
8条回答
  • 2020-11-30 06:05

    Your JSON data may have some properties that you do not have in your class. For mapping You can do simple custom mapping

    export class Employe{ ////
        static parse(json: string) {
               var data = JSON.parse(json);
                return new Employe(data.typeOfEmployee_id, data.firstName.. and others);
           }
    }
    

    and also specifying constructor in your Employee class.

    0 讨论(0)
  • 2020-11-30 06:06

    The reason that the compiler lets you cast the object returned from JSON.parse to a class is because typescript is based on structural subtyping.
    You don't really have an instance of an Employee, you have an object (as you see in the console) which has the same properties.

    A simpler example:

    class A {
        constructor(public str: string, public num: number) {}
    }
    
    function logA(a: A) {
        console.log(`A instance with str: "${ a.str }" and num: ${ a.num }`);
    }
    
    let a1 = { str: "string", num: 0, boo: true };
    let a2 = new A("stirng", 0);
    logA(a1); // no errors
    logA(a2);
    

    (code in playground)

    There's no error because a1 satisfies type A because it has all of its properties, and the logA function can be called with no runtime errors even if what it receives isn't an instance of A as long as it has the same properties.

    That works great when your classes are simple data objects and have no methods, but once you introduce methods then things tend to break:

    class A {
        constructor(public str: string, public num: number) { }
    
        multiplyBy(x: number): number {
            return this.num * x;
        }
    }
    
    // this won't compile:
    let a1 = { str: "string", num: 0, boo: true } as A; // Error: Type '{ str: string; num: number; boo: boolean; }' cannot be converted to type 'A'
    
    // but this will:
    let a2 = { str: "string", num: 0 } as A;
    
    // and then you get a runtime error:
    a2.multiplyBy(4); // Error: Uncaught TypeError: a2.multiplyBy is not a function
    

    (code in playground)


    Edit

    This works just fine:

    const employeeString = '{"department":"<anystring>","typeOfEmployee":"<anystring>","firstname":"<anystring>","lastname":"<anystring>","birthdate":"<anydate>","maxWorkHours":0,"username":"<anystring>","permissions":"<anystring>","lastUpdate":"<anydate>"}';
    let employee1 = JSON.parse(employeeString);
    console.log(employee1);
    

    (code in playground)

    If you're trying to use JSON.parse on your object when it's not a string:

    let e = {
        "department": "<anystring>",
        "typeOfEmployee": "<anystring>",
        "firstname": "<anystring>",
        "lastname": "<anystring>",
        "birthdate": "<anydate>",
        "maxWorkHours": 3,
        "username": "<anystring>",
        "permissions": "<anystring>",
        "lastUpdate": "<anydate>"
    }
    let employee2 = JSON.parse(e);
    

    Then you'll get the error because it's not a string, it's an object, and if you already have it in this form then there's no need to use JSON.parse.

    But, as I wrote, if you're going with this way then you won't have an instance of the class, just an object that has the same properties as the class members.

    If you want an instance then:

    let e = new Employee();
    Object.assign(e, {
        "department": "<anystring>",
        "typeOfEmployee": "<anystring>",
        "firstname": "<anystring>",
        "lastname": "<anystring>",
        "birthdate": "<anydate>",
        "maxWorkHours": 3,
        "username": "<anystring>",
        "permissions": "<anystring>",
        "lastUpdate": "<anydate>"
    });
    
    0 讨论(0)
提交回复
热议问题