How can I easily create a strongly typed object from an anonymous object in TypeScript?

6.2k views Asked by At

I have some JSON containing anonymous objects coming to my client-side. Is there some built-in mechanism or external library for converting these anonymous objects into strongly-typed TypeScript objects? Is there something like AutoMapper for doing this?

My objects are complex types, with complex types as properties.

3

There are 3 answers

0
howardlo On

I was looking for an easy way to convert json data from a web service to an interface too. Didn't found what I need but here is my solution. Noticed that I added a "Pet" interface and added another pet to your json. Also had to specify the anonymous object as "any". You can cut/paste this to TypeScript playground (http://www.typescriptlang.org/play/index.html) to see the results. Hope this helps.

let header = document.createElement("div");
header.textContent = "Test";
document.body.appendChild(header);

var people:any = [
    {
        "name": "bob", "height": 150, "pets": [{ "name": "spot", "species": "dog" }, {"name" : "violet", "species": "shark"}]
    },
    {
        "name": "jane", "height": 142, "pets": [{ "name": "lucy", "species": "cat" }]
    }
];

interface Pet {
    name: string;
    species: string;
}
interface Person {
    name: string;
    height: number;
    pets: Array<Pet>
}

class Foo {
    convertToObject = (person: Person) => person;
}


var person = new Foo().convertToObject(people[0]);

let div = document.createElement("div");
div.textContent = `hey ${person.name} I see you have ${person.pets.length} pet`;
document.body.appendChild(div);
4
Ryan Cavanaugh On

Get some sample data and place it in a .ts file:

var people = [
    {
        "name": "bob", "height": 150, "pets": [{ "name": "spot", "species": "dog" }]
    },
    {
        "name": "jane", "height": 142, "pets": [{ "name": "lucy", "species": "cat" }]
    }
];

Run tsc --declaration yourFile.ts

Now you'll have yourFile.d.ts:

declare var people: {
    "name": string;
    "height": number;
    "pets": {
        "name": string;
        "species": string;
    }[];
}[];

Replace declare var people: with interface Person, remove the trailing [], and (optionally) remove the quotes:

interface Person {
    name: string;
    height: number;
    pets: {
        name: string;
        species: string;
    }[];
}
0
DotBert On

Recently I created an AutoMapper implementation in TypeScript / JavaScript exactly for this scenario. I have put the code at GitHub (AutoMapperTS). You can also use the library directly using the automapper-ts NPM package or automapper-ts Bower package.

The library is almost fully documented. Furthermore, quite a lot of Jasmine unit tests are already available (code coverage is over 90%). They should provide you with some explanation of needed.

I hope this library suits your needs. Should you have any questions and/or remarks, please don't hesitate contacting me!

Happy coding!