nuyeo / NestJsBasic

따라하며 배우는 NestJS
7 stars 0 forks source link

mapped-types 모듈로 DTO 재사용성 높이기 #13

Open nuyeo opened 12 months ago

nuyeo commented 12 months ago
export class CreateBoardDto extends PickType(BoardEntity, ['title' ...,] as const) {}

이렇게 엔티티로부터 확장된 타입들을 사용해주세요. 코드가 타입을 통해 강하게 연결되는 게 좋다고 생각해요.

_Originally posted by @kakasoo in https://github.com/yeonod/NestJsBasic/pull/12#discussion_r1390198986_

nuyeo commented 12 months ago

npm i @nestjs/mapped-types 로 모듈 설치

기본적으로 DTO는 모든 필드가 필수 사항임

import { IsNotEmpty } from 'class-validator';

export class CreateBoardDto {
  @IsNotEmpty()
  title!: string;

  @IsNotEmpty()
  description!: string;
}

1. PartialType 모든 필드 값을 선택 사항으로 변경하여 재사용

export class UpdateBoardDto extends PartialType(CreateBoardDto) {}

2. PickType 필요한 필드 값을 지정하여 재사용

export class UpdateBoardDto extends PickType(CreateBoardDto, ['title'] as const) {}

3. OmitType 불필요한 필드 값을 제거하고 재사용

export class UpdateBoardDto extends OmitType(CreateBoardDto, ['title'] as const) {}

4. IntersectionType 두 개의 DTO를 하나로 합쳐서 재사용

export class AdditionBoardDto {
  @IsString()
  readonly director: string;
}
export class UpdateBoardDto extends IntersectionType(CreateBoardDto, AdditionBoardDto) {}

5. Composition 위 4개 중 2개의 타입을 결합해서 필요한 형태로 만들어 재사용

export class UpdateBoardDto extends PartialType( PickType(CreateBoardDto, ['title'] as const), ) {}

kakasoo commented 12 months ago

여담인데 class-validator, class-transform은 PickType 같이 MappedType 함수들을 사용하면 해당 프로퍼티의 데코레이터도 함께 옮겨주기 때문에 코드의 영향 범위를 파악하기 어려울 수 있어요. 그래서 이전 제 의견과 반대로 매 DTO는 독립적으로 만들되, PickType 대신 Pick 처럼 타입 레벨에서만 연결되게 하는 게 더 유리할 수도 있단 생각이 들어요.