从 JSON 对象初始化 TypeScript 对象

Shuvayan Ghosh Dastidar 2023年1月30日
  1. 将对象反序列化为 TypeScript 对象
  2. 反序列化 Typescript 对象的动态方法
从 JSON 对象初始化 TypeScript 对象

使用 TypeScript 处理 API 时,数据以字符串形式序列化,以便通过 Internet 协议进行传输。但是,使用从 API 接收到的数据需要在需要时反序列化为 TypeScript 类或对象。

本文将演示如何将接收到的对象转换为 TypeScript 类型的不同方法。这样就可以访问这种类型的支持、IDE 完成和其他功能。

将对象反序列化为 TypeScript 对象

JavaScript 中的 JSON 包很好地将普通对象解析为 TypeScript 对象。以下代码段演示了如何将 JSON 字符串解析为 TypeScript 对象。

var jsonString : string =`{
    "id": 1,
    "title" : "The Great Gatsby",
    "numPages" : 218
}`

interface BookInfo {
    id : number ;
    title : string ;
    numPages : number ;
}

var Book : BookInfo  = JSON.parse(jsonString);

console.log(Book);
console.log(Book.title);

输出:

{
  "id": 1,
  "title": "The Great Gatsby",
  "numPages": 218
} 
"The Great Gatsby" 

jsonString 可能是 API 响应的一部分,它以序列化字符串的形式出现。因此,如本例所示,变量 Book 将像普通 TypeScript 对象一样提供补全。

但是,这在类对象中包含函数和构造函数的情况下不起作用。考虑以下代码段,它演示了这一点。

class Animal{
    name : string;
    legs : number;
    constructor(name : string, legs : number){
        this.name = name;
        this.legs = legs;
    }

    getName(){
        return this.name;
    }
}

var jsonString : string = `{
    "name" : "Tiger",
    "legs" : 4
}`

var animalObj : Animal = JSON.parse(jsonString)
// this will give an error - animalObj.getName is not a function
animalObj.getName();

因此,从 animalObj 变量中,我们可以访问 namelegs 字段。但是,我们无法访问 getName() 函数,因为它是 Animal 类的一部分,无法直接解析但已初始化。

更改 Animal 类,以便 JSON 解析的对象可以访问成员函数。解析的对象必须被初始化。

class Animal{
    name : string;
    legs : number;
    constructor(name : string, legs : number){
        this.name = name;
        this.legs = legs;
    }

    getName(){
        return this.name;
    }

    toObject(){
        return {
            name : this.name, 
            legs : this.legs.toString()
        }
    }

    serialize() {
        return JSON.stringify(this.toObject());
    }

    static fromJSON(serialized : string) : Animal {
        const animal : ReturnType<Animal["toObject"]> = JSON.parse(serialized);

        return new Animal(
            animal.name,
            animal.legs
        )
    }
}

var jsonString : string = `{
    "name" : "Tiger",
    "legs" : 4
}`

var animalObj : Animal = Animal.fromJSON(jsonString);
console.log(animalObj)
// this will work now
console.log(animalObj.getName());

输出:

Animal: {
    "name": "Tiger",
    "legs": 4
} 
"Tiger"

反序列化 Typescript 对象的动态方法

现在,这种方法需要准确了解类的属性。下面讨论了一种更动态的反序列化 typescript 对象的方法。

在这种方法中,类的作者可以完全控制反序列化逻辑,并且可以使用多个类,如图所示。

interface Serializable<T> {
    deserialize(input : Object) : T;
}

class Furniture implements Serializable<Furniture> {
    price : number;
    deserialize(input) {
        this.price = Number(input.price);
        return this;
    }
    getPrice(){
       return this.price;
    }
}

class Chair implements Serializable<Chair> {
    id : string;
    furniture : Furniture;

    deserialize(input) {
        this.id =  input.id;
        this.furniture = new Furniture().deserialize(input.furniture);
        return this;
    }
}

var jsonString = `{
    "id" : "2323",
    "furniture" : {
        "price": 3000
    }
}`

var chair = new Chair().deserialize(JSON.parse(jsonString))
console.log(chair)

输出:

Chair: {
    "id": "2323",
    "furniture": {
        "price": 3000
    }
}
Shuvayan Ghosh Dastidar avatar Shuvayan Ghosh Dastidar avatar

Shuvayan is a professional software developer with an avid interest in all kinds of technology and programming languages. He loves all kinds of problem solving and writing about his experiences.

LinkedIn Website

相关文章 - TypeScript JSON