具有不同属性名称的Typescript映射类型

时间:2018-07-18 15:46:11

标签: angular typescript

我使用Angular 6 + TypeScript 2.7.2,并且我有一个需要使用ISelect[]类型的组件:

export interface ISelect {
    id: number;
    title: string;
}

因此,每次调用该组件时,我都需要传递一个ISelect[]。例如,我有一个IProject[],我需要将其映射到ISelect[]。在另一个示例中,我有IClient[],然后又需要将其映射到ISelect[],这里是{{1 }}:

IProject

我需要像伪代码一样映射它。

export interface IProject {
    id: number;
    name: string;
    code: string;
    clientId: number;
    status: number;
    level: number;
    masterKey: number;
    parentId?: number;
}

或者:

 myprojects: IProject[];
 myselect: ISelect[] = myprojects.Foreach.Map<ISelect>(id: id, title: name);

我需要这张地图:

export interface IClient {
    code: number,
    fullname: string,
    streetNumber: string,
    streetName: string,
    postalCode: string,
    city: string,
    isActive: boolean
}

我该如何进行映射。我宁愿避免在源数组中使用for循环。但每次需要转换时,我可能会有不同的映射。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

如果您不想每次都具有可转换为ISelect的新类时都编写映射方法,则可以编写一个通用的转换器方法。

这是一种尝试,您必须指定将映射到id的键,然后 title界面中的ISelect

  convert<T, TK extends keyof T>(arr: T[], idKey: TK, titleKey: TK) : any[] {
    return arr.map( item => {
      return { id: item[idKey], title: item[titleKey] };
    });
  }

然后用IClientIProject调用它-类型脚本将为您做一些类型检查。

您可以对IClient的数组使用类似的内容

let arrOfClients: IClient[] = [
  {
     code: 1, 
    fullname: 'test', 
    streetNumber: '12', 
    streetName: 'street', 
    postalCode: '12', 
    city: 'Bangalore', 
    isActive: true 
  }
];
let converted: ISelect[] = convert(arrOfClients, "code", "fullname");

类似地,您可以对IProject

数组使用类似的方法
let converted: ISelect[] = convert(arrOfProjects, "id", "name");

答案 1 :(得分:1)

您可以使用object destructuring参数在传递给.map()的函数中定义映射:

myselect: ISelect[] = myprojects.map(({ id, name: title }) => ({ id, title }));

这种方法也适用于IClient,如下所示:

myselect: ISelect[] = myClients.map(({ code: id, fullname: title }) => ({ id, title }));

答案 2 :(得分:1)

类似的事情会起作用

myselect: ISelect[] = this.myprojects.map(p => { return <ISelect>{ id: p.id, title: p.name } });