Typescript将json反序列化为具有多种类型的集合

LPa*_*ins 3 serialization json typescript

我正在为项目使用typescript,需要将集合序列化为json,将其保存到文件中,然后将该文件反序列化为类似的集合.该集合看起来像:

elements: Array<tool>
Run Code Online (Sandbox Code Playgroud)

我的工具界面如下所示:

export interface tool {
    name: string;
    draw(context:any);
}
Run Code Online (Sandbox Code Playgroud)

并且工具实现看起来像:

export class textTool implements tool {
    name: string;
    fontSize:number;
    fontType:string;
    draw(context:any){
        // draws the control...
    }
}
Run Code Online (Sandbox Code Playgroud)

我的工具界面实现很少:textTool,imageTool和rectangleTool.我需要解决的问题是,当我将文件内容反序列化为工具集合时,我只获得一个常规对象而不是textTool的实例.

我正在使用JSON.stringify(elements)创建一个json并JSON.parse(jsonText)反序列化.

据我所知,解析器无法知道应该创建哪个类型的实例,因为json文本没有关于它的信息.我想添加一个字段或其他东西来识别我需要哪个类实例并手动"新"该类.任何我不需要手动将json解析为工具集合(具有适当类型)的选项?

Ale*_* L. 6

如你所说,你可以添加一个字段type,在type-string和implementation-class之间创建一个映射,然后转换代码将非常简单:

export interface tool {
    type: string;
    name: string;
    draw(context:any): void;
}

class textTool implements tool {
    type:string = 'textTool';
    name:string;
    fontSize:number;
    fontType:string;

    draw(context:any):void {
    }
}

const typeMapping:any = {
    'textTool' : textTool
    //all other types
};
let json = '[{"type":"textTool", "name": "someName", "fontSize": 11}]';
let elements: Array<tool> = JSON.parse(json).map((i:any) => {
    let target:any = new typeMapping[i.type];
    for (const key in i) {
        target[key] = i[key];
    }
    return target;
});
Run Code Online (Sandbox Code Playgroud)

*克隆代码非常简单,但它对于普通对象来说已经足够了.