1

I have a very simple class

export class Foo {

    name: string;

    index: number;

    toFullString(): string {
        return `${this.name} | ${this.index}`;
    }
}

I get elements of this class from a server and cast json to this class:

.map(response => response.json() as Foo)

Now what happens is that after I call toFullString() method it fails since this is not the "real" Foo object as it would be in say C#.

So what is the proper way of achieving real Foo object, preferably without the need of writing your own constructors and so on.

The type safety in TypeScript is a joke sometimes really.

Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207
  • Possible duplicate of [How do I cast a JSON object to a typescript class](http://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class) – chimmi Nov 09 '16 at 16:03
  • Either you're going to have to write your own constructor or you'll have to take your returned obejcts and append the function (technically legal JS) with `for(let obj of responseObjects) { obj['toFullString'] = function ... }`. One you don't want, and the other is a little sketchy. – silentsod Nov 09 '16 at 16:04
  • @chimmi this does not seem to be a duplicate. I already can cast, that's not the problem. The problem is that ordinary casting is not enough to get the "real" class... – Ilya Chernomordik Nov 09 '16 at 18:55

2 Answers2

1

You could create the Object and give it the JSON values.

.map(res => this.onResponse(res))

-

function onResponse(res:any){
    this.foo = new Foo();
    this.foo.name = res['name'];
    ...
}

Or give the JSON values to the constructor of Foo

this.foo = new Foo(res['name'], ...);
Ploppy
  • 14,810
  • 6
  • 41
  • 58
1

Either you're going to have to write your own constructor or you'll have to take your returned obejcts and append the function (technically legal JS) with for(let obj of responseObjects) { obj['toFullString'] = function ... }. One you don't want, and the other is a little sketchy.

The constructor method you have already seen but I'll repeat here:

constructor(public name, public index) {
    this.name = name;
    this.index = index;
}

You could also do it in the map which is the same thing.

masterFoo: Foo = new Foo();

mapFoo(responseObject: any) {
    <...>
    responseObject['toFullString'] = masterFoo.toFullString;
    <...>
  }

The auto mapping works for data objects only, and it's a limitation due to JS being the underlying language of it all.

Here's a plunker demonstrating appending the function to a Plain Old JavaScript Object: http://plnkr.co/edit/BBOthl0rzjfEq3UjD68I?p=preview

silentsod
  • 8,165
  • 42
  • 40
  • That looks like quite hacky unfortunately, so I guess I'll stick with constructor or ordinary mapping if nothing better exists... Though I suppose there are some sort of AutoMapper for TypeScript. – Ilya Chernomordik Nov 09 '16 at 18:58