Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json property alias in typescript

Let's say I want to get a data from Visual Studio TFS and the response (as json) is in this kind of format:

{
    "Microsoft.VSTS.Scheduling.StoryPoints": 3.0,
    // ......
}

There's dot in the property name. Reading from other questions I found out that I can read that json in typescript by using an interface like this

export interface IStory { // I don't think this kind of interface do me any help
    "Microsoft.VSTS.Scheduling.StoryPoints": number
}

And then I can use the property with this syntax:

var story = GetStoryFromTFS();
console.log(story["Microsoft.VSTS.Scheduling.StoryPoints"]);

But I'd prefer not to call the property like this, since the intellisense won't able to help me finding which property I want to use (because I call the property using a string).

In C# there is a JsonProperty attribute which enable me to create a model like this:

public class Story
{
    [JsonProperty(PropertyName = "Microsoft.VSTS.Scheduling.StoryPoints")]
    public double StoryPoints { get; set; }
}

And then I can use the property this way:

var story = GetStoryFromTFS();
Console.WriteLine(story.StoryPoints);

This way the intellisense will able to help me finding which property I want to use.

Is there something like JsonProperty attribute in typescript? Or is there any other, better way, to achieve this in typescript?

like image 339
samAlvin Avatar asked Jul 13 '17 08:07

samAlvin


1 Answers

You have many options. Just keep in mind that all of these options require you to pass the original data to the class that will access it.

Map the values.

class StoryMap {
    constructor(data: IStory) {
        this.StoryPoints = data["Microsoft.VSTS.Scheduling.StoryPoints"];
     }

    StoryPoints: number;
}

Wrap the data.

class StoryWrap {
    constructor(private data: IStory) {}

    get StoryPoints(): number { return this.data["Microsoft.VSTS.Scheduling.StoryPoints"] };
}

Build a decorator to map the data.

function JsonProperty(name: string) {
    return function DoJsonProperty(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.get = function () {
            return this.data[name];
        }
        descriptor.set = function (value) {
            this.data[name] = value;
        }
    }
}

class StoryDecorator
{
    constructor(private data: IStory) {}

    @JsonProperty("Microsoft.VSTS.Scheduling.StoryPoints")
    get StoryPoints(): number { return 0 };

}
like image 74
Rodris Avatar answered Sep 28 '22 05:09

Rodris