【问题标题】:Typescript deserializing json into collection with multiple typesTypescript将json反序列化为具有多种类型的集合
【发布时间】:2016-11-01 05:39:18
【问题描述】:

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

elements: Array<tool>

我的工具界面如下:

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

工具实现如下所示:

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

我有几个工具接口的实现:textTool、imageTool 和 rectangleTool。我需要解决的问题是,当我将文件内容反序列化为工具集合时,我得到的只是一个常规对象,而不是 textTool 的实例。

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

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

【问题讨论】:

  • 有很多选择:您可以将不同的类型保存到不同的文件中,或者保存到一个文件中,但每种类型都有不同的“部分”。您还可以包装每个对象,例如:{ "type": "textTool", "object": { ... } }
  • @NitzanTomer 我同意它可能会起作用,我想仔细检查是否还有其他东西或者我错过了什么。
  • “更好”不是客观标准。 可能有一种方法可以通过更具体地说明“更好”的含义来使其更客观,但因为它是这个问题引起的意见而不是事实。
  • 您知道使用JSON.stringifyJSON.parse 不允许您包含函数,对吧?因为您的界面确实包含 draw 函数。
  • @MikeMcCaughan。谢谢,我把问题改得更客观了。

标签: json serialization typescript


【解决方案1】:

正如你所说,你可以添加一个字段type,创建类型字符串到实现类之间的映射,然后转换代码将非常简单:

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

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

【讨论】:

  • 谢谢。让我在我的环境中尝试一下。
  • 这是(2019 年)的发展方向吗?
【解决方案2】:

对于普通对象试试吧:

function deserialize<T>(json): T[] {
    let collection: T[] = [];
    json.map((item: T) => {
        collection.push(item);
    });
    return collection;
}

然后调用它:

let tools: tool[] = deserialize<textTool>(json);

【讨论】:

    猜你喜欢
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多