在 TypeScript 和 NestS 中将类转换为类/对象(实体到 DTO)

Posted

技术标签:

【中文标题】在 TypeScript 和 NestS 中将类转换为类/对象(实体到 DTO)【英文标题】:Transform class to class/object (Entity to DTO) in TypeScript and NestS 【发布时间】:2020-05-25 03:19:51 【问题描述】:

如何转换数据库实体User

class User 
  public firstName: string;
  public lastName: string;
  public phone?: string;
  public email: string;
  public status: EUserState;
  public tokens: Token[];
  public password: string;


进入DTO实体GetUserDTO

class GetUserDTO 
  public id: number;
  public firstName: string;
  public lastName: string;
  public phone?: string;
  public email: string;

在 TypeScript 中?我正在使用@nestjsclass-validatorclass-transformer 包,但我没有找到任何方法来使用它们来实现这一点。

有人会说,拥有 DTO 对此毫无意义,但我们在服务器和客户端之间共享 DTO 以维护 API 结构。

有什么想法吗?

【问题讨论】:

【参考方案1】:

有几种方法可以实现你想要的

    您可以使用static 函数从DomainDTO 手动将Domain 模型映射到DTOs
export class Domain 
   ...
   static toDTO(domain: Domain) 
      // mapping goes here
   

export class Dto 
   ...
   static fromDomain(domain: Domain) 
      // mapping goes here
   

    您可以使用第 3 方库:automapper-ts@wufe/mapper@nartc/automapper(我的库)或 morphism

class-transformer 也可以被认为是一个映射器,但是,如果你想从一个模型映射到另一个模型,那么class-transformer 就不能真正做到这一点。

【讨论】:

在干净的架构中,域不应该依赖于基础设施层,这意味着Domain类不应该知道DTO类。所以应该首选第二个选项Dto.fromDomain【参考方案2】:

首先,使用class-transformer的classToPlain将Entity转成纯json

然后,使用 class-transformer 的 plainToClass 将纯 json 转换为 DTO 如下所示

  public async getAll(): Promise<ItemDTO[]> 
    return await this.repo.find()
      .then(items => items.map(e=>plainToClass(ItemDTO, classToPlain(e),  excludeExtraneousValues: true )));
  

此外,让我们在 DTO 中使用 Exclude、Expose of class-transformer 来获取您希望客户端看到的客户端数据。

@Exclude()
export class ItemDTO implements Readonly<ItemDTO> 
  @ApiProperty( required: true )
  @IsUUID()
  @Expose()
  id: string;

【讨论】:

以上是关于在 TypeScript 和 NestS 中将类转换为类/对象(实体到 DTO)的主要内容,如果未能解决你的问题,请参考以下文章

在 Typescript 和 AWS Lambda 中将 DynamoDB 数据格式化为普通 JSON

在 Typescript 中将 $state 和 $stateParams 的引用添加到 $rootScope(角度)

如何在 Typescript 中将具有动态键的对象设置为 React 状态

如何在 Typescript 中将 ref prop 和 useRef 与 Lottie 文件一起使用?

如何在同一个项目中将 Typescript 与 Angular CLI 和 Express/Node 一起使用?

在 Angular 应用程序中将 JSON 解析为 Typescript 类