JSON 到 TypeScript 类实例? [英] JSON to TypeScript class instance?

查看:20
本文介绍了JSON 到 TypeScript 类实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了很多研究,但我对我的发现并不完全满意.只是为了确定这是我的问题:将 JSON 反序列化为 TypeScript 运行时类实例的最强大、最优雅的自动化解决方案是什么?

I've done quite some research, but I'm not totally satisfied with what I found. Just to be sure here's my question: What is actually the most robust and elegant automated solution for deserializing JSON to TypeScript runtime class instances?

假设我有这门课:

class Foo {
  name: string;
  GetName(): string { return this.name };
}

然后说我得到了这个用于反序列化的 JSON 字符串:

And say I got this JSON string for deserialization:

{"name": "John Doe"}

获取名称设置为John Doe"且方法 GetName() 的 Foo 类实例的最佳和最易于维护的解决方案是什么?我问得非常具体,因为我知道反序列化为纯数据对象很容易.我想知道是否有可能获得具有工作方法的类实例,而无需进行任何手动解析或任何手动数据复制.如果完全自动化的解决方案是不可能的,那么下一个最佳解决方案是什么?

What's the best and most maintainable solution for getting an instance of a Foo class with the name set to "John Doe" and the method GetName() to work? I'm asking very specifically because I know it's easy to deserialize to a pure data-object. I'm wondering if it's possible to get a class instance with working methods, without having to do any manual parsing or any manual data copying. If a fully automated solution isn't possible, what's the next best solution?

推荐答案

这个问题很广泛,所以我将给出几个解决方案.

This question is quite broad, so I'm going to give a couple of solutions.

以下是使用 Helper Method 的示例,您可以根据需要对其进行更改:

Here's an example of using a Helper Method that you could change to fit your needs:

class SerializationHelper {
    static toInstance<T>(obj: T, json: string) : T {
        var jsonObj = JSON.parse(json);

        if (typeof obj["fromJSON"] === "function") {
            obj["fromJSON"](jsonObj);
        }
        else {
            for (var propName in jsonObj) {
                obj[propName] = jsonObj[propName]
            }
        }

        return obj;
    }
}

然后使用它:

var json = '{"name": "John Doe"}',
    foo = SerializationHelper.toInstance(new Foo(), json);

foo.GetName() === "John Doe";

高级反序列化

这也可以通过将您自己的 fromJSON 方法添加到类中来允许一些自定义反序列化(这与 JSON.stringify 已经使用了 toJSON 方法,如下所示):

This could also allow for some custom deserialization by adding your own fromJSON method to the class (this works well with how JSON.stringify already uses the toJSON method, as will be shown):

interface IFooSerialized {
    nameSomethingElse: string;
}

class Foo {
  name: string;
  GetName(): string { return this.name }

  toJSON(): IFooSerialized {
      return {
          nameSomethingElse: this.name
      };
  }

  fromJSON(obj: IFooSerialized) {
        this.name = obj.nameSomethingElse;
  }
}

然后使用它:

var foo1 = new Foo();
foo1.name = "John Doe";

var json = JSON.stringify(foo1);

json === '{"nameSomethingElse":"John Doe"}';

var foo2 = SerializationHelper.toInstance(new Foo(), json);

foo2.GetName() === "John Doe";

解决方案 2:基类

另一种方法是创建自己的基类:

Solution 2: Base Class

Another way you could do this is by creating your own base class:

class Serializable {
    fillFromJSON(json: string) {
        var jsonObj = JSON.parse(json);
        for (var propName in jsonObj) {
            this[propName] = jsonObj[propName]
        }
    }
}

class Foo extends Serializable {
    name: string;
    GetName(): string { return this.name }
}

然后使用它:

var foo = new Foo();
foo.fillFromJSON(json);

使用基类实现自定义反序列化的方法有太多不同,所以我将根据您的需要进行选择.

There's too many different ways to implement a custom deserialization using a base class so I'll leave that up to how you want it.

这篇关于JSON 到 TypeScript 类实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆