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

3

9

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.

Touraine answered 29/8, 2013 at 17:6 Comment(1)
You need to write the mapper yourself (or download code from the net) -- for example, most libraries will have a mixin function that allows you to mixin properties from one object to another. Then just cast your strongly-typed object into any and pass it into the mapper with your JSON object. The strongly-typed object will be filled just like any plain old JavaScript object.Stenson
A
9

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;
    }[];
}
Ambit answered 29/8, 2013 at 17:16 Comment(4)
This is nice, but I was looking for something that could do it for me on the fly.Touraine
@RyanShripat when you say "on the fly" do you mean automatically generate the file, or do it at runtime?Cletis
I want to be able to say: var people = [...] /* anonymous JSON object */; then say: People p = ConvertAnonToStrong(people);, with errors at run-time if the conversion doesn't work.Touraine
"with errors at run-time if the conversion doesn't work" - TypeScript is a compile time only language that produces pure JavaScript, so it can't provide runtime type constraints.Partial
T
3

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!

Tamalatamale answered 23/8, 2015 at 0:14 Comment(0)
A
1

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);
Aspen answered 3/9, 2017 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.