JSON转换为TypeScript类实例? [英] JSON to TypeScript class instance?

查看:107
本文介绍了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方法的示例,可以根据需要进行更改:

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天全站免登陆