如何将 JSON 对象解析为 TypeScript 对象

新手上路,请多包涵

我目前正在尝试将收到的 JSON 对象转换为具有相同属性的 TypeScript 类,但我无法让它工作。我究竟做错了什么?

员工类

export class Employee{
    firstname: string;
    lastname: string;
    birthdate: Date;
    maxWorkHours: number;
    department: string;
    permissions: string;
    typeOfEmployee: string;
    note: string;
    lastUpdate: Date;
}

员工字符串

{
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": <anynumber>,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
    //I will add note later
}

我的尝试

let e: Employee = new Employee();

Object.assign(e, {
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 3,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
});

console.log(e);

链接到 Typescript Playground

原文由 moessi774 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 998
2 个回答

编译器允许您将从 JSON.parse 返回的对象转换为类的原因是因为 typescript 基于结构子类型

您实际上并没有 Employee 的实例,您有一个具有相同属性的对象(如您在控制台中看到的)。

一个更简单的例子:

 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);

操场上的代码

没有错误,因为 a1 满足类型 A 因为它具有所有属性,并且 logA 函数即使没有运行时错误也可以调用不是 A 的实例,只要它具有相同的属性。

当你的类是简单的数据对象并且没有方法时,这很有效,但是一旦你引入了方法,事情往往会中断:

 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

操场上的代码%3B%20%2F%2F%20Error%3A%20Uncaught%20TypeError%3A%20a2.multiplyBy%20is%20not%20a%20function))


编辑

这工作得很好:

 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);

操场上的代码%3B%0Aconsole.log(employee1)%3B))

如果您尝试在对象不是字符串时使用 JSON.parse

 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);

然后你会得到错误,因为它不是一个字符串,它是一个对象,如果你已经以这种形式拥有它,那么就没有必要使用 JSON.parse

但是,正如我所写的,如果您采用这种方式,那么您将没有该类的实例,而只是一个与类成员具有相同属性的对象。

如果你想要一个实例,那么:

 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>"
});

原文由 Nitzan Tomer 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用语法“as”执行此操作吗?

 async getProfile(): Promise<Contact> {
      const url: string = this.baseApi;

      const response = await this.http.get(url).toPromise()
      return JSON.parse(response.json()) as Contact;
    }

原文由 Onur Dikmen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进