ts-deco
v1.0.18
Published
TypeScript decorator utilities for Node.js with strict validation standards
Maintainers
Readme
ts-deco
검증과 Swagger 작성을 동시에 처리하는 함축적인 데코레이터 라이브러리
TypeScript decorator utilities with strict validation standards and automatic Swagger documentation
하나의 데코레이터로 타입 검증과 Swagger API 문서화를 동시에 처리하는 Node.js/TypeScript용 DTO 데코레이터 라이브러리입니다. NestJS와 Node.js (Express, Fastify 등) 모든 프로젝트에서 사용할 수 있습니다.
설치
npm install ts-deco빠른 시작
Property 데코레이터 하나로 검증과 Swagger 문서 작성을 동시에 처리할 수 있습니다:
NestJS에서 사용
import { Property } from 'ts-deco';
class CreateUserDto {
@Property({ type: String, optional: false })
name: string;
@Property({ type: Number, min: 0, max: 120, optional: false })
age: number;
}
// NestJS Controller에서 자동으로 Swagger 문서 생성 및 검증 수행
@Post()
create(@Body() dto: CreateUserDto) {
// 자동 검증 완료, Swagger 문서에 자동 반영
}Node.js/Express에서 사용
import { Property } from 'ts-deco';
class CreateUserDto {
@Property({ type: String, optional: false })
name: string;
@Property({ type: Number, min: 0, max: 120, optional: false })
age: number;
}
// Express 라우트에서 검증 및 Swagger 문서 생성
app.post('/users', validationMiddleware(CreateUserDto), (req, res) => {
// 자동 검증 완료, Swagger 문서에 자동 반영
});기본 사용법
Property 데코레이터 하나로 모든 타입을 처리할 수 있습니다:
import { Property } from 'ts-deco';
class CreateUserDto {
@Property({ type: String, optional: false })
name: string;
@Property({ type: Number, min: 0, max: 120, optional: false })
age: number;
@Property({ type: String, optional: true })
email?: string;
@Property({ type: Boolean, optional: false })
isActive: boolean;
@Property({ type: Date, optional: true })
createdAt?: Date;
}주요 기능
⚡ 하나의 데코레이터로 검증 + Swagger 문서화
Property 데코레이터는 타입에 따라 자동으로 적절한 검증을 적용하고, 동시에 Swagger API 문서를 자동 생성합니다.
- ✅ 검증:
class-validator를 사용한 런타임 타입 검증 - ✅ Swagger:
@nestjs/swagger호환 메타데이터로 자동 API 문서 생성 - ✅ 함축적: 하나의 데코레이터로 두 가지 작업을 동시에 처리
- ✅ 호환성: NestJS와 Node.js (Express, Fastify 등) 모두 지원
Property 데코레이터 (권장)
Property 데코레이터는 타입에 따라 자동으로 적절한 검증과 Swagger 스키마를 적용합니다.
기본 타입
import { Property } from 'ts-deco';
class UserDto {
// 문자열
@Property({ type: String, optional: false })
name: string;
// 숫자 (범위 검증)
@Property({
type: Number,
min: 1,
max: 100,
optional: false
})
score: number;
// 날짜
@Property({ type: Date, optional: true })
birthDate?: Date;
// 불린
@Property({ type: Boolean, optional: false })
isActive: boolean;
}열거형 (Enum)
import { Property } from 'ts-deco';
enum UserRole {
ADMIN = 'admin',
USER = 'user',
GUEST = 'guest',
}
class UserDto {
@Property({
enum: UserRole,
optional: false
})
role: UserRole;
// 특정 값 제외
@Property({
enum: UserRole,
exclude: [UserRole.GUEST],
optional: false
})
allowedRole: UserRole;
}배열
import { Property } from 'ts-deco';
class UserDto {
@Property({
type: String,
isArray: true,
optional: false
})
tags: string[];
@Property({
type: Number,
isArray: true,
min: 1,
max: 10,
optional: false
})
scores: number[];
}빈 값 검증 (isNotEmpty)
문자열이나 배열이 비어있지 않은지 검증하려면 isNotEmpty 옵션을 사용합니다:
import { Property } from 'ts-deco';
class UserDto {
@Property({
type: String,
optional: false,
isNotEmpty: true,
notEmptyMessage: '이름은 필수이며 비어있을 수 없습니다'
})
name: string;
@Property({
type: String,
isArray: true,
optional: false,
isNotEmpty: true,
arrayMessage: '태그는 배열이어야 합니다',
notEmptyMessage: '태그는 최소 1개 이상 필요합니다'
})
tags: string[];
}커스텀 에러 메시지
import { Property } from 'ts-deco';
class UserDto {
@Property({
type: Number,
min: 1,
max: 100,
minMessage: '최소값은 1 이상이어야 합니다',
maxMessage: '최대값은 100 이하여야 합니다',
validatorMessage: '숫자 타입이어야 합니다',
optional: false
})
score: number;
}개별 데코레이터
더 세밀한 제어가 필요한 경우 개별 데코레이터를 사용할 수 있습니다:
import { DtoString, DtoNumber, DtoDate, DtoBoolean, DtoEnum } from 'ts-deco';
class UserDto {
@DtoString({ optional: false, isNotEmpty: true })
name: string;
@DtoNumber({ min: 0, max: 120, optional: false })
age: number;
@DtoDate({ optional: true })
birthDate?: Date;
@DtoBoolean({ optional: false })
isActive: boolean;
@DtoEnum(UserRole, { optional: false })
role: UserRole;
}개별 데코레이터 옵션
각 개별 데코레이터는 Property 데코레이터와 동일한 옵션을 지원합니다:
- DtoString:
optional,isNotEmpty,isArray,validatorMessage,notEmptyMessage,arrayMessage및 Swagger 옵션 - DtoNumber:
optional,isNotEmpty,isArray,isInt,min,max,minMessage,maxMessage,validatorMessage,notEmptyMessage,arrayMessage및 Swagger 옵션 - DtoDate:
optional,isNotEmpty,isArray,validatorMessage,notEmptyMessage,arrayMessage및 Swagger 옵션 - DtoBoolean:
optional,isNotEmpty,isArray,validatorMessage,notEmptyMessage,arrayMessage및 Swagger 옵션 - DtoEnum:
optional,isNotEmpty,isArray,exclude,validatorMessage,notEmptyMessage,arrayMessage및 Swagger 옵션
Controller 데코레이터 (NestJS 스타일)
검증과 Swagger 문서 작성을 동시에 처리하는 DTO 데코레이터 외에도, API 엔드포인트의 Swagger 문서를 자동 생성하는 Controller 데코레이터를 제공합니다.
사용 예제
NestJS에서 사용
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody, ApiQuery } from 'ts-deco';
@ApiTags('Users')
@Controller('users')
export class UserController {
@ApiOperation({ summary: '사용자 생성' })
@ApiResponse({ status: 200, description: '사용자 생성 성공' })
@ApiResponse({ status: 400, description: 'Validation 실패' })
@ApiBody({ type: CreateUserDto, required: true })
@Post()
create(@Body() dto: CreateUserDto) {
// ...
}
@ApiOperation({ summary: '사용자 업데이트' })
@ApiResponse({ status: 200, description: '사용자 업데이트 성공' })
@ApiParam({ name: 'id', type: String, required: true })
@ApiBody({ type: UpdateUserDto, required: true })
@Patch(':id')
update(@Param('id') id: string, @Body() dto: UpdateUserDto) {
// ...
}
@ApiOperation({ summary: '사용자 목록 조회' })
@ApiQuery({ name: 'page', type: Number, required: false, minimum: 1 })
@ApiQuery({ name: 'limit', type: Number, required: false, minimum: 1, maximum: 100 })
@Get()
findAll(@Query('page') page?: number, @Query('limit') limit?: number) {
// ...
}
}Node.js/Express에서 사용
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody, ApiQuery } from 'ts-deco';
class UserRoutes {
@ApiTags('Users')
@ApiOperation({ summary: '사용자 생성' })
@ApiResponse({ status: 200, description: '사용자 생성 성공' })
@ApiResponse({ status: 400, description: 'Validation 실패' })
@ApiBody({ type: CreateUserDto, required: true })
static createUser(req: Request, res: Response) {
// ...
}
@ApiTags('Users')
@ApiOperation({ summary: '사용자 업데이트' })
@ApiResponse({ status: 200, description: '사용자 업데이트 성공' })
@ApiParam({ name: 'id', type: String, required: true })
@ApiBody({ type: UpdateUserDto, required: true })
static updateUser(req: Request, res: Response) {
// ...
}
}
app.post('/api/users', validationMiddleware(CreateUserDto), UserRoutes.createUser);
app.patch('/api/users/:id', validationMiddleware(UpdateUserDto), UserRoutes.updateUser);Controller 데코레이터 목록
ApiTags
클래스 또는 메서드에 Swagger 태그를 설정합니다.
@ApiTags('Users')
@ApiTags('Admin', 'Users') // 여러 태그ApiOperation
메서드에 Swagger 작업(operation) 정보를 설정합니다.
@ApiOperation({
summary: '사용자 생성',
description: '새로운 사용자를 생성합니다',
operationId: 'createUser',
deprecated: false,
tags: ['Users']
})ApiResponse
메서드에 Swagger 응답 정보를 설정합니다. 여러 번 사용 가능합니다.
@ApiResponse({ status: 200, description: '성공' })
@ApiResponse({ status: 400, description: 'Validation 실패' })
@ApiResponse({ status: 404, description: '사용자를 찾을 수 없음' })ApiParam
경로 파라미터에 대한 Swagger 정보를 설정합니다.
@ApiParam({ name: 'id', type: String, required: true, description: '사용자 ID' })ApiQuery
쿼리 파라미터에 대한 Swagger 정보를 설정합니다.
@ApiQuery({ name: 'page', type: Number, required: false, minimum: 1 })
@ApiQuery({ name: 'limit', type: Number, required: false, minimum: 1, maximum: 100 })ApiBody
요청 본문에 대한 Swagger 정보를 설정합니다.
@ApiBody({ type: CreateUserDto, description: '사용자 생성 데이터' })Property 데코레이터 옵션
공통 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| type | String \| Number \| Date \| Boolean | 필수 | 필드 타입 |
| enum | object | - | 열거형 타입 (type 대신 사용) |
| optional | boolean | false | 선택적 필드 여부. true일 경우 IsOptional 검증 적용 |
| isArray | boolean | false | 배열 타입 여부 |
| isNotEmpty | boolean | false | 빈 값 검증 여부. true일 경우 IsNotEmpty 검증 적용 (optional이 false일 때만) |
| validatorMessage | string | - | 타입 검증 실패 메시지 |
| arrayMessage | string | - | 배열 검증 실패 메시지 |
| notEmptyMessage | string | - | 빈 값 검증 실패 메시지 (isNotEmpty가 true일 때 사용) |
숫자 타입 전용 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| min | number | - | 최소값 |
| max | number | - | 최대값 |
| isInt | boolean | false | 정수만 허용 |
| minMessage | string | - | 최소값 검증 실패 메시지 |
| maxMessage | string | - | 최대값 검증 실패 메시지 |
열거형 전용 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| exclude | any[] | [] | 제외할 enum 값들 |
Swagger 옵션 (자동 생성)
Property 데코레이터는 자동으로 Swagger API 문서를 생성합니다. @nestjs/swagger의 ApiPropertyOptions를 모두 사용할 수 있어 NestJS와 완벽하게 호환됩니다:
검증 + Swagger 자동 생성 예제
@Property({
type: String,
description: '사용자 이름', // Swagger 문서에 표시
example: '홍길동', // Swagger 문서에 표시
optional: false // 검증 규칙 + Swagger required
})
name: string;이렇게 작성하면:
- ✅ 검증:
name이 필수이며 문자열이어야 함 - ✅ Swagger: API 문서에
name필드가 필수 문자열로 자동 등록됨
@Property({
type: String,
description: '사용자 이름',
example: '홍길동',
optional: false
})
name: string;사용 예제
기본 사용법
import { Property } from 'ts-deco';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';
class CreateUserDto {
// 필수 문자열 필드
@Property({ type: String, optional: false })
name: string;
// 선택적 이메일 필드
@Property({ type: String, optional: true })
email?: string;
// 필수 숫자 필드 (범위 제한)
@Property({ type: Number, min: 0, max: 120, optional: false })
age: number;
}
// 사용 예제
const userData = {
name: '홍길동',
age: 25
};
const dto = plainToInstance(CreateUserDto, userData);
const errors = await validate(dto);
if (errors.length > 0) {
console.log('검증 실패:', errors);
} else {
console.log('검증 성공:', dto);
}빈 값 검증 예제
import { Property } from 'ts-deco';
class PostDto {
// 빈 문자열 허용 안 함
@Property({
type: String,
optional: false,
isNotEmpty: true,
notEmptyMessage: '제목은 필수이며 비어있을 수 없습니다'
})
title: string;
// 빈 문자열 허용 (기본값)
@Property({
type: String,
optional: false,
isNotEmpty: false // 기본값
})
description: string; // "" 허용
// 빈 배열 허용 안 함
@Property({
type: String,
isArray: true,
optional: false,
isNotEmpty: true,
notEmptyMessage: '태그는 최소 1개 이상 필요합니다'
})
tags: string[];
}검증 동작 방식
optional 옵션
optional: false(기본값): 필드가 필수입니다- 값이
undefined또는null이면IsDefined검증 실패 isNotEmpty: true인 경우IsNotEmpty검증 적용 (빈 문자열, 빈 배열 등도 검증)
- 값이
optional: true: 필드가 선택적입니다- 값이 없어도 통과 (
IsOptional검증 적용) - 값이 있으면 타입 검증 수행
- 값이 없어도 통과 (
isNotEmpty 옵션
isNotEmpty: false(기본값): 빈 값 검증 없음optional: false일 때IsDefined검증만 수행
isNotEmpty: true: 빈 값 검증 수행optional: false일 때만 적용됨IsNotEmpty검증 적용 (빈 문자열"", 빈 배열[]등도 검증 실패)
검증 우선순위
optional: true→IsOptional적용 (값이 없어도 통과)optional: false+isNotEmpty: true→IsNotEmpty적용 (빈 값 검증)optional: false+isNotEmpty: false→IsDefined적용 (값 존재 여부만 검증)- 타입 검증 (IsString, IsNumber, IsDate, IsBoolean, IsEnum 등)
- 추가 검증 (min/max, exclude 등)
왜 ts-deco를 사용해야 할까요?
🎯 검증과 Swagger 작성을 한 번에
기존에는 검증 데코레이터와 Swagger 데코레이터를 따로 작성해야 했습니다:
// 기존 방식 (번거로움)
@IsString()
@IsNotEmpty()
@ApiProperty({ type: String, description: '사용자 이름', example: '홍길동' })
name: string;ts-deco를 사용하면 하나의 데코레이터로 처리합니다:
// ts-deco 방식 (간결함)
@Property({
type: String,
optional: false,
isNotEmpty: true,
description: '사용자 이름',
example: '홍길동'
})
name: string;🌟 주요 장점
- ✅ 함축적: 하나의 데코레이터로 검증과 Swagger 문서화 동시 처리
- ✅ 간결함: 코드 중복 제거, 가독성 향상
- ✅ 타입 안전성: 엄격한 타입 체크로 컴파일 타임 에러 방지
- ✅ 자동 문서화: Swagger API 문서 자동 생성
- ✅ 호환성: NestJS와 Node.js (Express, Fastify 등) 모두 지원
- ✅ 런타임 안정성: 명확한 에러 메시지 제공
엄격한 검증 규칙
ts-deco는 다음과 같은 엄격한 검증 규칙을 적용합니다:
- ✅ 타입 안전성: 모든 데코레이터는 엄격한 타입 체크를 거칩니다
- ✅ 명시적 검증: 옵션과 검증 규칙이 명확하게 정의되어 있습니다
- ✅ 일관된 동작: 모든 데코레이터가 동일한 기준으로 동작합니다
- ✅ 런타임 안정성: 잘못된 타입이나 값에 대해 명확한 에러를 제공합니다
- ✅ 자동 문서화: 검증 규칙이 Swagger 문서에 자동으로 반영됩니다
검증 규칙
- 타입 불일치 시 즉시 에러: 잘못된 타입이 전달되면 명확한 에러 메시지 제공
- 범위 검증:
min/max옵션이 제공되면 반드시 검증 - 필수 필드 검증:
optional: false인 경우 값이 없으면 에러 - 빈 값 검증:
isNotEmpty: true인 경우 빈 문자열, 빈 배열 등도 검증 실패 - 배열 검증:
isArray: true인 경우 배열 타입만 허용 - 열거형 검증:
enum이 제공되면 해당 값만 허용
⚠️ 주의: 모든 데코레이터는 동일한 타입이어야 합니다.
데코레이터 지원
이 라이브러리는 TypeScript legacy decorators를 지원합니다. Stage 3 decorators는 아직 지원하지 않습니다.
의존성
이 라이브러리는 다음 패키지들을 dependencies로 포함하고 있어, npm install ts-deco 실행 시 자동으로 함께 설치됩니다:
| 패키지 | 버전 | 용도 |
|--------|------|------|
| class-transformer | ^0.5.0 | 타입 변환 데코레이터 |
| class-validator | ^0.14.0 | 검증 데코레이터 |
| reflect-metadata | ^0.1.13 | 메타데이터 리플렉션 (데코레이터 지원) |
| @nestjs/swagger | ^7.0.0 | Swagger API 문서화 데코레이터 (선택적) |
참고:
- 별도로 설치할 필요 없이
npm install ts-deco만 실행하면 모든 의존성이 자동으로 설치됩니다.- 이 라이브러리는 NestJS에 종속되지 않습니다.
class-validator와class-transformer는 독립적인 라이브러리이며, NestJS와 Node.js (Express, Fastify 등) 모든 프로젝트에서 사용할 수 있습니다.@nestjs/swagger는 Swagger API 문서화 기능을 사용할 때만 필요합니다. 문서화 기능을 사용하지 않더라도 검증 기능은 정상적으로 동작합니다.- 하나의 데코레이터로 검증과 Swagger 문서 작성을 동시에 처리하므로 코드 중복을 줄이고 유지보수를 쉽게 만듭니다.
지원 환경
- ✅ NestJS: 완벽한 호환성, NestJS 프로젝트에서 바로 사용 가능
- ✅ Node.js: Express, Fastify 등 모든 Node.js 프레임워크에서 사용 가능
- ✅ TypeScript: TypeScript 프로젝트 필수 (타입 안전성 보장)
- ✅ Swagger: 자동 API 문서 생성 지원
라이선스
ISC License
