관리자 페이지를 위한 API를 구현하던 도중 쿼리 파라미터를 통해 Boolean값을 받아야 했다.

export class GetFacilityReportListDto extends PaginationDto {
  @ApiProperty({
    type: Boolean,
    description: '운영자 확인 여부',
    required: false,
  })
  @IsOptional()
  isChecked: boolean;
}

하지만 isChecked=false를 담아도 서버에선 true로 반환 되고 있었다.

원인 분석

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
      transform: true,
      **transformOptions: {
        enableImplicitConversion: true,
      },**
    }),
  );

이 코드는 class-transformer라이브러리를 설정하는 코드다.

이 중 enableImplicitConversion 옵션은 true로 설정하면, 암묵적 형 변환을 허용한다는 뜻으로.

class-transformer의 데코레이터를 사용하지 않고도 지정된 타입으로 변환 시켜준다.

Untitled

Untitled

Untitled

test를 입력하면 isChecked: true로 변환되는 모습을 확인 할 수 있다. 그 외 null, false를 넣어도 true로 변환된다.

왜 true로 변환 되었을까?

class-transformer의 내부 동작을 확인해보면 답을 알 수 있다.

https://github.com/typestack/class-transformer/blob/a073b5ea218dd4da9325fe980f15c1538980500e/src/TransformOperationExecutor.ts#L108-L110

} else if (targetType === Boolean && !isMap) {
  if (value === null || value === undefined) return value;
  return Boolean(value);
}

value가 null또는 undefined가 아니면