Javascript / Typescript:以角度将一个数组类转换为另一个数组类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript / Typescript:以角度将一个数组类转换为另一个数组类相关的知识,希望对你有一定的参考价值。

如何使用下面的两个类将数组列表从源映射到目标?需要DTO映射到查找数组。已经测试了地图功能,仍然无法正常工作。另外,我们应该将mapFromSourceAddressDto方法设置为单独的Export函数,还是在Lookup类本身内部,是否会更容易?

[后端DTO API模型可能会改变,因此尝试创建一种类型安全的方式来映射子集列,并在DTO列名称发生更改时得到通知。

export class SourceOfAddressDto {
    sourceOfAddressId: number | undefined;
    sourceOfAddressCode: string | undefined;
    sourceOfAddressDescription: string | undefined;
    sourceOfAddressLabel: string | undefined;
    createDate: date;
    userId: string;
}

export class SourceOfAddressLookup {
    sourceOfAddressId: number | undefined;
    sourceOfAddressCode: string | undefined;
    sourceOfAddressDescription: string | undefined;
    sourceOfAddressLabel: string | undefined;       
}

export function mapFromSourceOfAddressDto(sourceOfAddressDto: SourceOfAddressDto){
    const sourceOfAddressLookup = new SourceOfAddressLookup();
    sourceOfAddressLookup .sourceOfAddressId = sourceOfAddressDto.sourceOfAddressId
    sourceOfAddressLookup .sourceOfAddressCode = sourceOfAddressDto.sourceOfAddressCode;
    sourceOfAddressLookup .sourceOfAddressDescription = sourceOfAddressDto.sourceOfAddressDescription
    sourceOfAddressLookup .sourceOfAddressLabel = sourceOfAddressDto.sourceOfAddressLabel;

    return sourceOfAddressLookup ;
}

目标: Take an Array<SourceofAddressDto> ---> Array<SourceOfAddressLookup>

尝试的解决方案:

寻找更清洁的方式,

public addressSourceList: Array<SourceOfAddressLookup>; 

if (addressSourceListDto.length > 0){
    for (let i = 0; i < addressSourceListDto.length; ++i ) {
      this.addressSourceList[i] = mapFromSourceOfAddressDto(addressSourceListDto[i])
    }
  }
答案

我认为您可能使事情变得比需要的复杂。

在这种情况下,确保类型安全的更有效方法是首先定义两个打字稿接口。

用于您的DTO数据结构(我想是来自api请求)。另一个用于您的“目标”对象结构。

interface SourceOfAddressDto {
  sourceOfAddressId?: number;
  sourceOfAddressCode?: string;
  sourceOfAddressDescription?: string;
  sourceOfAddressLabel?: string;
  createDate: string;
  userId: string;
}

interface SourceOfAddress {
  sourceOfAddressId?: number;
  sourceOfAddressCode?: string;
  sourceOfAddressDescription?: string;
  sourceOfAddressLabel?: string;
}

您可以使用指定的返回类型分别定义地图函数

const mapItems = (item:SourceOfAddressDto):SourceOfAddress[] => {
  return {
    sourceOfAddressId: item.sourceOfAddressId;
    sourceOfAddressCode: item.sourceOfAddressCode;
    sourceOfAddressDescription: item.sourceOfAddressDescription;
    sourceOfAddressLabel: item.sourceOfAddressLabel;
  }
};

当您检索异步数据时,您可以直接将其映射:

const data = await fetch("http://api") as SourceOfAddressDto[];
const mappedData = data.map(mapItems);
另一答案

我假设您的DTO是具有方法的成熟类

class SourceOfAddressDto {
    sourceOfAddressId: number | undefined;
    sourceOfAddressCode: string | undefined;
    sourceOfAddressDescription: string | undefined;
    sourceOfAddressLabel: string | undefined;
    createDate: Date;
    userId: string;
    constructor(createDate: Date, userId: string) {
        this.createDate = createDate; this.userId = userId;
    }
}

但是查找类型可以是仅具有某些相同属性的接口。如果您希望此类型具有名称,则可以通过以下方式进行操作:

// if you must name this type, you can do this:
interface SourceOfAddressLookup extends Pick<SourceOfAddressDto,
    "sourceOfAddressCode" |
    "sourceOfAddressDescription" |
    "sourceOfAddressId" |
    "sourceOfAddressLabel"
    > { }

无论如何,总的来说,我会使用像pluck()这样的函数来获取一个现有对象并通过复制属性列表来创建一个新对象:

function pluck<T, K extends keyof T>(t: T, ...k: K[]) {
    return k.reduce((a, k) => (a[k] = t[k], a), {} as Pick<T, K>)
}

然后您的mapFromSourceOfAddressDto函数可以像这样使用它:

function mapFromSourceOfAddressDto(obj: SourceOfAddressDto): SourceOfAddressLookup {
    return pluck(
        obj,
        "sourceOfAddressId",
        "sourceOfAddressCode",
        "sourceOfAddressDescription",
        "sourceOfAddressLabel"
    );
}

我们可以确保它可以正常工作:

const dto = new SourceOfAddressDto(new Date(), "abc");
dto.sourceOfAddressCode = "cod";
dto.sourceOfAddressDescription = "descrip";
dto.sourceOfAddressLabel = "lab";
dto.sourceOfAddressId = 1;

const lookup = mapFromSourceOfAddressDto(dto);

console.log(JSON.stringify(lookup));

/* {
"sourceOfAddressId":1,
"sourceOfAddressCode":"cod",
"sourceOfAddressDescription":"descrip",
"sourceOfAddressLabel":"lab"
}
*/

对我很好。希望这可以为您提供指导。祝你好运!

Playground link to code

以上是关于Javascript / Typescript:以角度将一个数组类转换为另一个数组类的主要内容,如果未能解决你的问题,请参考以下文章

配置具有公共依赖项的 TypeScript 项目以构建多个纯 JavaScript 输出文件

Javascript / Typescript:以角度将一个数组类转换为另一个数组类

javascript学习+Vue学习+项目开发

如何通过 javascript/typescript 获取“事件”对象的特定元素

如何使用 bit 在 javascript 项目中创建 typescript 组件?

在 TypeScript 中使用最新的 JavaScript 功能,例如 ES2018