Home > database >  How to convert TypeScript array to generic array of class
How to convert TypeScript array to generic array of class

Time:02-05

I have JSON source array with all values as strings. I'm trying to convert it to another array of typed objects. I'm getting errors. How to properly write this code? Thank you.

Error 1: Conversion of type '({ Id: string; CompanyName: string; ...)[]' to type 'Dest' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

Erorr 2: ../grid-second.component.ts:12:10 - error TS2740: Type 'Dest' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more. 12 public gridData: any[] = destination;

export const source = [{
    'Id': 'ALFKI',
    'CompanyName': 'Alfreds Futterkiste',
    'DOB': '01/31/2000' // may not exists
}, {
    'Id': 'ANATR',
    'CompanyName': 'Ana Bokov Emparedados y helados',
}, 

export class Dest{
    public Id: string = "";
    public CompanyName: string = "";
    public DOB?: Date
}

export const destination = <Dest>source;  // Error 1.

In the Angular component:

public gridData: any[] = destination;  // Error 2.

enter image description here

CodePudding user response:

You can add a constructor to your class and create an instances of it using map:

class Dest {
    public Id: string = "";
    public CompanyName: string = "";
    public DOB?: Date;

    constructor(id: string, companyName: string, dob: string | undefined) {
        this.Id = id;
        this.CompanyName = companyName;

        // TODO: not seeing Timezone in source objects.
        this.DOB = dob ? new Date(dob): undefined;
    }
}

const destination: Dest[] = source.map(x => new Dest(x.Id, x.CompanyName, x.DOB));

If you dont really need a class and you dont want to play with new - you can utilize Interfaces or Types. But anyway, you will need to convert string DOB to Date DOB:

interface IDest {
    Id: string;
    CompanyName: string;
    DOB?: Date;
}

const destination: IDest[] = source.map(x => ({...x, DOB: x.DOB ? new Date(x.DOB) : undefined}));

Playground: click

CodePudding user response:

I like to use Object.assign() for this purpose. Usually I'm doing this in a RXJS Map as part of getting data back from a server.

However, you can also use the array map function:

newSource = source.map(element => Object.assign(new Dest(),  element));

Although, given your code, with a hard coded array I'd probably just create the values directly as part of the array creation, as opposed to processing it later:

export const source = [Object.assign(new Dest, {
    'Id': 'ALFKI',
    'CompanyName': 'Alfreds Futterkiste',
    'DOB': '01/31/2000' // may not exists
}), Object.assign(new Dest, {
    'Id': 'ANATR',
    'CompanyName': 'Ana Bokov Emparedados y helados',
})
]
  • Related