Typescript JSON string to class

15,853

Solution 1

You don't necessarily need a class here. You can just use an interface

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

Then you can just write:

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

If you data comes from the server, you will probably have it in a variable of type any, and you can just assign it to an array of that type and it will work as expected.

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

In typescript you don't need a class implementing an interface. Any object literal that satisfies the interface contract will do.

If your data is still in string for you can just use JSON.parse(jsonString) to parse the string to JavaScript objects.

See playground here

Solution 2

You will need to create a constructor for your class, and call it for each item in the list you receive.

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

You can check it out in the playground here.

Solution 3

There is a problem when MyObject has 50 or more properties...

Add a constructor in your MyObject class so that it extends your json object.

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

    methodOnMyObject() {...}
}

In your ajax callback, create the MyObject object from your json Object:

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

I detailed the solution in that post.

Share:
15,853
Ben
Author by

Ben

I'm a game developer (Unity, BennuGD, Div Game Studio) I'm a professional web developer (Angular) I'm a professional mobile app developer (Xamarin Forms)

Updated on June 04, 2022

Comments

  • Ben
    Ben almost 2 years

    Let be this JSON string:

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

    Let be this class:

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

    How can I cast this JSON string to list of MyObject?

    If I do:

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

    It returns a list of Object instead of a list of MyObject

  • Ben
    Ben over 7 years
    Thanl you for your reply. But the returned object is still not an MyObject type. When I log it in the console it says that it's an Object. What am I doing wrong?
  • Ben
    Ben over 7 years
    I have seen in many posts that it's possible to do it without to map each property, as suggested by @Titian Cernicova-Dragomir. What is the truth? Is there really a way to do it without mapping?
  • Titian Cernicova-Dragomir
    Titian Cernicova-Dragomir over 7 years
    It doesn't need to say MyObject, it will work. Typescript types are more about describing the shape of a Javascript Object. If the object satisfies the contract it should be fine. Is there a specific error you are getting? Does the Object you see in the console have the id and text properties ? If so it should work.
  • Titian Cernicova-Dragomir
    Titian Cernicova-Dragomir over 7 years
    And since MyObject is now an interface, it will not have any actual presence in JS output, interfaces are wiped away by TS compilation, they are just there to allow you to describe the shape of JS objects
  • Ben
    Ben over 7 years
    Yes, the object has the properties. But what I don't understand is that if I instantiate a new MyObject and map the properties, the console show the MyObject type.
  • Ben
    Ben over 7 years
    And if the given JSON doesn't fit the class description (for exemple if the JSON has a property which doesn't exists in the class), the generated object still have this property. Should he not throw an error?
  • Nitzan Tomer
    Nitzan Tomer over 7 years
    @Ben It depends what you're looking for. If you want a data object only then you can go with interfaces as TitianCernicovaDragomir answered. However, if you want to also have methods on the objects then you need to instantiate class instances, and toskv solution is the one you're looking for.
  • toskv
    toskv over 7 years
    @Ben if you need to add some more methods you need my solution, if you just need to use the objects as they come from the server the interface solution is more appropiate. :)
  • Titian Cernicova-Dragomir
    Titian Cernicova-Dragomir over 7 years
    If the JSON does not fit the description there will be no error you just can't access any extra properties from typescript (unless you add them to the interface as well)
  • Titian Cernicova-Dragomir
    Titian Cernicova-Dragomir over 7 years
    @Ben Nitzan Tomer is right about using classes if you plan to also have methods, but if your looking for just simple object to hold data there is no need to create an extra clss
  • stomy
    stomy over 6 years
    If you want to use jquery $.extend method in your typescript file you need to enable jquery in your typescript files first by running npm install --save @types/jquery see this answer.
  • stomy
    stomy over 6 years
    Should it not be let newObject = new MyObject( JSON.parse(json) ); instead?
  • Sudeep Rane
    Sudeep Rane about 6 years
    @toskv .map() function looks good on const JSON data but it's not applicable on type HTTPResponse. Thanks anyway.
  • toskv
    toskv about 6 years
    you didn't specify how you come to get the array. I just started from the array onwards. :)