Salman Salman - 1 year ago 67
TypeScript Question

Typescript: Cast type in subscribe or in map

I receive a json from the backend which contains an array of

Here is the client class:

export class Client {
private id:number;
private firstname: String;
private lastname: String;
private phone:String;
private address:String;
private country:String;
private Security_No:String;

I am looking for easiest way to cast the received
to a
currently i store the json in an attribute, and later i go throw it and extract data fram it. but it seems that, there should be an easier way?

populateClientData() {

Answer Source

You can not cast json data (that is, js objects) into classes.
Well, you can, but then you don't really have instances of the class but objects that satisfy the class interface.

Simple example:

class Point {
    x: number;
    y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;

let a = {
    x: 5,
    y: 5
} as Point;
console.log(a); // Object {x: 5, y: 5}

let b = new Point(5, 5);
console.log(b); // Point {x: 5, y: 5}

The compiler won't complain about a not being an instance of Point because it satisfies the Point interface, so these are valid:

function log(point: Point) {
    console.log(`(${ point.x }, ${ point.y })`);

log(a); // fine
log(b); // fine

(code in playground)

It works this way because:

One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.

More on duck typing.

As for you specific problem, you can use your class as an interface or just make it into an interface:

interface Client {
    firstname: String;
    lastname: String;

And then (in both cases):

this._httpClientService.getAllClients().subscribe((res) => { = res.json() as Client[]

But if you'll use your class (and not the interface) then the properties must be public and not private.

If you wish to use your class as a class and not interface then casting won't do, you'll need to:

this._httpClientService.getAllClients().subscribe((res) => { = res.json().map(item => new Client(data));

And you'll need to have a constructor for Client which accepts the interface and assigns the values to its members.