如何使用抽象继承将JSON编码和解码为TypeScript模型?

如何使用抽象继承将JSON编码和解码为TypeScript模型?,json,typescript,Json,Typescript,我有一个TypeScript数据模型,其中一个类包含一个具有抽象数据类型的列表。我想把这个模型编码成JSON,然后从JSON解码 让我们假设以下简化模型: class Vendor { vehicles: Vehicle[]; } abstract class Vehicle { wheels: number; } class Bike extends Vehicle { } class Car extends Vehicle { doors: number; }

我有一个TypeScript数据模型,其中一个类包含一个具有抽象数据类型的列表。我想把这个模型编码成JSON,然后从JSON解码

让我们假设以下简化模型:

class Vendor {
    vehicles: Vehicle[];
}

abstract class Vehicle {
    wheels: number;
}

class Bike extends Vehicle { }

class Car extends Vehicle {
    doors: number;
}
问题是:在运行时,我们不知道车辆列表中每个元素的数据类型

到目前为止,我所尝试的:

我将数据类型作为className字段添加到JSON字符串中:

class Vendor {
    vehicles: Vehicle[];
}


interface VehicleJSON {
    className: string;
    wheels: number;
}
abstract class Vehicle {
    wheels: number;

    toJSON(): VehicleJSON {
        return Object.assign({ className: this.constructor.name }, this);
    }
}


class Bike extends Vehicle { }


interface CarJSON extends VehicleJSON {
    doors: number;
}
class Car extends Vehicle {
    doors: number;

    toJSON(): CarJSON {
        return Object.assign({ className: this.constructor.name }, this);
    }
}
这将为每个自行车和每个汽车对象添加一个className字段。编码似乎像intendet一样工作

现在转到解码部分。不幸的是,我没有想出一个好的解决办法。这看起来有点笨重:

[...]

interface VehicleJSON {
    className: string;
    wheels: number;
}
abstract class Vehicle {
    public static fromJSON(json: any): Vehicle {
        switch (json.className) {
            case Bike.constructor.name:
                return Bike.fromJson(json as VehicleJSON);

            case Car.constructor.name:
                return Car.fromJSON(json as CarJSON);

            default: 
            throw new Error();
        }
    }
    [...]
}


class Bike extends Vehicle {
    public static fromJSON(json: VehicleJSON): Bike {
        const vehicle = Object.create(Bike.prototype);
        return Object.assign(vehicle, json);
    }
}


interface CarJSON extends VehicleJSON {
    doors: number;
}
class Car extends Vehicle {
    public static fromJSON(json: CarJSON): Car {
        const vehicle = Object.create(Car.prototype);
        return Object.assign(vehicle, json);
    }
    [...]
}
由于循环依赖关系,上面的代码可以编译,但不会运行。父类Vehicle使用来自其子类的静态函数,corse的子类从其父类扩展而来

我收到以下错误消息:

class Bike extends vehicle_1.Vehicle

TypeError: Class extends value undefined is not a constructor or null

我希望你能帮我解决我的问题,并想出更好的解决办法。提前谢谢

您需要的是stringification replacer函数的解析对应项,即解析恢复器函数:

reviver函数允许您检查JSON提供的键/值对,并返回您自己的值,其中可以包括您自己的自定义类

另外,如果您不介意我吹嘘自己的小项目,我已经制作了自己的JSON字符串化器/解析器,专门处理自定义数据类型:

上面的一个选项将以这样的方式对自定义对象进行编码,即您仍然可以使用标准JSON以及适当的恢复器函数来解析数据