【问题标题】:Typescript JSON string to classTypescript JSON字符串到类
【发布时间】:2017-03-03 11:14:30
【问题描述】:

假设为这个 JSON 字符串:

[
    {
        "id": 1,
        "text": "Jon Doe"
    },
    {
        "id": 1,
        "text": "Pablo Escobar"
    }
]

让我们成为这个班级:

export class MyObject{
    id: number;
    text: string;
}

如何将此 JSON 字符串转换为 MyObject 列表?

如果我这样做:

console.log(<MyObject[]>JSON.parse(json_string));

它返回Object 的列表而不是MyObject 的列表

【问题讨论】:

标签: json object typescript casting


【解决方案1】:

实现此目的的另一种方法:

var data: any = getFromServer();
var myObjectArray = data as MyObject;

或者:

var data: any = getFromServer();
var myObjectArray = <MyObject>dataMyObject;

【讨论】:

    【解决方案2】:

    当 MyObject 有 50 个或更多属性时出现问题...

    在您的 MyObject 类中添加一个构造函数,以便它扩展您的 json 对象。

    export class MyObject {
        constructor( json: any )
        {
          $.extend(this, json);
        }
        id : number;
        text : string;
    
        methodOnMyObject() {...}
    }
    

    在您的 ajax 回调中,从您的 json 对象创建 MyObject 对象:

    let newObject = new MyObject( json );
    newObject.methodOnMyObject();
    

    我在post中详细说明了解决方案。

    【讨论】:

    • 如果你想在你的 typescript 文件中使用 jquery $.extend 方法,你需要首先在你的 typescript 文件中通过运行 npm install --save @types/jquery see this answer 来启用 jquery。
    • 不应该是let newObject = new MyObject( JSON.parse(json) );吗?
    【解决方案3】:

    你不一定需要在这里上课。你可以只使用一个界面

    export interface MyObject{
      id: number;
      text: string;
    }
    

    那么你可以写:

    var myObjArray : MyObject[] =  [
      {
        "id": 1,
        "text": "Jon Doe"
      },
      {
        "id": 1,
        "text": "Pablo Escobar"
      }
    ];
    

    如果您的数据来自服务器,您可能会将其保存在 any 类型的变量中,您只需将其分配给该类型的数组,它就会按预期工作。

    var data: any = getFromServer();
    var myObjectArray:MyObject[] = data;
    

    在打字稿中,您不需要实现接口的类。任何满足接口契约的对象字面量都可以。

    如果您的数据仍在字符串中,您可以使用 JSON.parse(jsonString) 将字符串解析为 JavaScript 对象。

    见游乐场here

    【讨论】:

    • 感谢您的回复。但是返回的对象仍然不是MyObject 类型。当我将它登录到控制台时,它说它是Object。我做错了什么?
    • 不需要说MyObject,就可以了。 Typescript 类型更多地是关于描述 Javascript 对象的形状。如果对象满足合同,它应该没问题。您是否遇到了特定错误?您在控制台中看到的对象是否具有 id 和 text 属性?如果是这样,它应该可以工作。
    • 而且由于 MyObject 现在是一个接口,它不会在 JS 输出中实际存在,接口被 TS 编译擦除,它们只是用来描述 JS 对象的形状
    • 如果 JSON 不符合描述,则不会出现错误,您只是无法从 typescript 访问任何额外的属性(除非您也将它们添加到界面中)
    • @Ben Nitzan Tomer 如果您还打算拥有方法,那么使用类是正确的,但如果您只是寻找简单的对象来保存数据,则无需创建额外的 clss
    【解决方案4】:

    您需要为您的类创建一个构造函数,并为您收到的列表中的每个项目调用它。

    export class MyObject{
        constructor(public id: number, public text: string) { }
    }
    
    let data = [
      {
        "id": 1,
        "text": "Jon Doe"
      },
      {
        "id": 1,
        "text": "Pablo Escobar"
      }
    ];
    
    let objects = data.map(o => new MyObject(o.id, o.text));
    

    您可以在操场上查看here

    【讨论】:

    • 我在许多帖子中看到,正如@Titian Cernicova-Dragomir 所建议的那样,无需映射每个属性就可以做到这一点。真相是什么?真的有办法不用映射吗?
    • @Ben 这取决于你在寻找什么。如果您只想要一个数据对象,那么您可以使用 TitianCernicovaDragomir 回答的接口。但是,如果您还想在对象上拥有方法,那么您需要实例化类实例,而 toskv 解决方案就是您要寻找的解决方案。
    • @Ben 如果您需要添加更多方法,您需要我的解决方案,如果您只需要使用来自服务器的对象,则接口解决方案更合适。 :)
    • @toskv .map() 函数在 const JSON 数据上看起来不错,但不适用于 HTTPResponse 类型。还是谢谢。
    • 您没有指定获取数组的方式。我刚从数组开始。 :)
    猜你喜欢
    • 2017-11-13
    • 2016-06-16
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2017-11-28
    • 1970-01-01
    相关资源
    最近更新 更多