tl;dr: I need to have the compiled Typescript prototype definitions applied to objects I have defined to be of that class.
Situation: I need to extend a JavaScript object by some business logic defined in a typescript class.
This might look somewhat like:
class Address
{
constructor(
public Street: string,
public Number: number,
public Zip: number,
public City: string)
{ }
public get FullAddress()
{
return this.Street + ' ' + this.Number + ', '
+ this.Zip + ' ' + this.City;
}
}
The compiled JS adds the code to extend the object prototype by FullAddress
. If I call new Address('Somestreet', 5, 3564, 'SomeCity')
everything works like a charm.
The Problem: when I get some JS object (in my case using angular's $http
)
$http.get('/api/address').then((answer: AngularPromise<Address[]>) =>
{
console.log(answer.data[0].FullAddress());
});
I can call the function FullAddress
on the object since in Typescript the function is defined on the class definition.
Now when I execute the code in the browser answer.data.FullAddress()
is not defined (which makes sense since Typescript just provides the type definition and never touched the object.
Attempted Solution : One possible solution would be calling the constructor for each object (somewhat like following)
$http.get('/api/address').then((answer: AngularPromise<Address[]>) =>
{
for(var i = 0; i < answer.data.length; i++)
{
answer.data[0] = new Address(answer.data[0].Street, ans.....);
}
console.log(answer.data[0].FullAddress());
});
and maybe overload the Address
constructor to accept the complete object to reduce boilerplate.
The actual Question: Since the Object I need is a way more complex nested structure than that simple Address construct described here, above solution would require me to write an enormous amount of boilerplate and I feel like there has to be a better solution to that problem.
Had this same issue! One way to go, as you said is to make a constructor and feed all the info in - a bit tedious and seems wrong. We ended up making a MapTo
function that can map a generic object to a strong class:
public static MapTo(jsonObject, nameSpace, classType) {
var instance = new classType();
for (var prop in jsonObject) {
if (!jsonObject.hasOwnProperty(prop)) {
continue;
}
if (jsonObject[prop] == null) {
instance[prop] = null;
} else if (typeof jsonObject[prop] === 'object') {
if (nameSpace[prop]) {
instance[prop] = this.MapTo(jsonObject[prop], nameSpace, nameSpace[prop]);
} else {
instance[prop] = jsonObject[prop];
}
} else {
instance[prop] = jsonObject[prop];
}
}
return instance;
}
And the usage would be:
var strongAddress = MapTo(answer.data[0], Models, Models.Address); //I assumed your class was in a namespace called "Models"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.