
Decorator
함수 선언 없이 기능 확장
≒ Python의 데코레이터
≒ Java의 에노테이션
class CreateUserDto {
@IsEmail()
@MaxLength(60)
readonly email: string;
@IsString()
@Matches(/^[A-Za-z\d!@#$%^&*()]{8,30}$/)
readonly password: string;
}
예시 :
function deco(target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log('데코레이터가 평가됨'); } class TestClass { @deco test(){ console.log('함수 호출됨'); } }
test()실행 시 :데코레이터가 평가됨 함수 호출됨
코드
function first(){
console.log("first 평가");
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("first 호출");
}
}
function second(){
console.log("second 평가");
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("second 호출");
}
}
class ExampleClass{
@first()
@second()
method(){
console.log("method 호출");
}
}
출력
first 평가
second 평가
second 호출
first 호출
method 호출
데코레이터의 호출 순서가 함수 스택과 같음
코드
function reportableClassDeco<T extends { new (...args: any[]): {} }>(constructor: T){
return class extends constructor{
reportingURL = "http://www.example.com";
};
}
@reportableClassDeco
class BugReport{
type = "report";
title: string;
constructor(t: string){
this.title = t;
}
}
const bug = new BugReport("Needs dark mode");
console.log(bug);
출력
{type: 'report', title: 'Needs dark mode', reportingURL: 'http://www.example.com"}
클래스에 없던 속성을 추가
interface PropertyDescriptor{
configurable?: boolean; // 속성의 정의 수정 가능 여부
enumerable?: boolean; // 열거형 여부
value?: any; // 속성 값
writable: boolean; // 수정 가능 여부
get?(): any; // getter
set?(v: any): void; // setter
}
function HandleError(){
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor){
...
}
}
target : 정적 멤버가 속한 클래스의 생성자 함수이거나 인스턴스 멤버에 대한 클래스의 프로토타입
propertyKey : 멤버의 이름
descriptor : 멤버의 속성 설명자
@Enumerable(true)
get getName(){
return this.name;
}
function format(formatString: string){
return function(target: any, propertyKey: string): any{
let value = target[propertyKey];
}
}
target : 정적 멤버가 속한 클래스의 생성자 함수이거나 인스턴스 멤버에 대한 클래스의 프로토타입
propertyKey : 멤버의 이름
return function(target: any, propertyKey: string, parameterIndex: number){
...
}
target : 정적 멤버가 속한 클래스의 생성자 함수이거나 인스턴스 멤버에 대한 클래스의 프로토타입
propertyKey : 멤버의 이름
parameterIndex : 매개변수가 함수에서 몇 번째 위치에 선언되었는지를 나타내는 인덱스
한용재 저, 『NestJS로 배우는 백엔드 프로그래밍』, 제이펍, 2022.