3

Is there a way of using mapped-types with swagger and class-transformer

Got a example of whats going wrong here: https://stackblitz.com/edit/nestjs-starter-demo-aq1sw2?file=src/dtos/user-descriptor.dto.ts

The DTOs:

ProjectDescriptorDto

// import { PickType } from '@nestjs/mapped-types';
import { PickType } from '@nestjs/swagger';
import { ProjectDto } from './project.dto';

export class ProjectDescriptorDto extends PickType(ProjectDto, [
  'id',
  'title',
] as const) {}

ProjectDto

import { Expose, Type } from 'class-transformer';
import { UserDescriptorDto } from './user-descriptor.dto';

export class ProjectDto {
  @Expose()
  id: number;

  @Expose()
  description: string;

  @Expose()
  @Type(() => UserDescriptorDto)
  starredBy: UserDescriptorDto[];

  @Expose()
  title: string;
}

UserDescriptorDto

// import { PickType } from '@nestjs/mapped-types';
import { PickType } from '@nestjs/swagger';
import { UserDto } from './user.dto';

export class UserDescriptorDto extends PickType(UserDto, [
  'id',
  'firstName',
  'lastName',
  'email',
] as const) {}

UserDto

import { ProjectDescriptorDto } from './project-descriptor.dto';
import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';

export class UserDto {
  id: number;
  firstName: string;
  lastName: string;
  email: string;
  @ApiProperty({
    isArray: true,
    type: ProjectDescriptorDto,
  })
  @Type(() => ProjectDescriptorDto)
  favourites: ProjectDescriptorDto[];
}

So in the example using PickType from @nestjs/mapped-types compiles the code but it won't generate the correct swagger specs for the extended class

Using PickType from @nestjs/swagger is required to generate the swagger spec correctly but in combination with @Type() decorator from the class-transform package, the code won't compile correctly:

TypeError: Cannot read properties of undefined (reading 'prototype')
    at Object.PickType (/home/projects/nestjs-starter-demo-aq1sw2/node_modules/@nestjs/swagger/dist/type-helpers/pick-type.helper.js:13:38)
    at Object.eval (/home/projects/nestjs-starter-demo-aq1sw2/dist/dtos/project-descriptor.dto.js:7:46)
    at Object.function (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:11:119417)
    at Module._compile (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:167880)
    at Object.Module._extensions..js (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:168239)
    at Module.load (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:166317)
    at Function.Module._load (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:163857)
    at Module.require (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:166635)
    at i (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:6:435073)
    at _0x4139bb (https://nestjs-starter-demo-aq1sw2.jw.staticblitz.com/blitz.88a7151d177878d00bf438b30e057ed5805fdcd2.js:11:119029)

So the question is; is there a way around this using mapped-types or will I instead have to not extend the descriptors. The current work-around is to use:

SomeDescriptorDto implements Pick<SomeDto, 'id' | ...> {
    id: number;
    // variables
}
HaaLeo
  • 10,065
  • 3
  • 44
  • 55
JDU
  • 31
  • 3
  • how do you resolve this issue? – Huy Bui Dac Apr 19 '23 at 07:53
  • Been a while now so not sure if its changed for more recent versions, but I wasn't able to resolve this because of differences in the overwritten mapped types from `@nestjs/swagger`. I stuck with the `implements` work-around – JDU Apr 20 '23 at 09:26

0 Answers0