그럼에도 불구하고

👨‍💻

[TypeScript] 데코레이터(Decorator)란? 본문

TypeScript/TypeScript basics

[TypeScript] 데코레이터(Decorator)란?

zenghyun 2023. 5. 23. 01:10

 

오늘은 데코레이터에 대해 알아보겠습니다.

 

 

[ 데코레이터 (decorator) ]

데코레이터(Decorator)는 타입스크립트에서는 실험적으로 도입된 기능입니다. 타입스크립트의 데코레이터는 자바(Java)의 어노테이션이나 파이썬(Python)의 데코레이터와 유사한 기능을 합니다. 그러나 자바 어노테이션은 컴파일 타임에 영향을 받지만, 타입스크립트 데코레이터는 컴파일 타임에 영향을 받지 않기 때문에 오히려 파이썬(Python)의 데코레이터와 거의 비슷하다고 합니다. 

 

데코레이터는 일종의 함수로 코드 조각을 장식해 주는 역할을 하며, 타입스크립트에서는 그 기능을 함수로 구현한 것입니다. 

메서드, 클래스, 프로퍼티, 등 위에 @로 시작하는 데코레이터를 선언하여 장식하면 코드가 실행됐을 때, 데코레이터 함수가 실행되어, 장식한 멤버를 보다 많은 기능을 수행하게 만들어 주는 것입니다. 

 

데코레이터를 잘 사용하면 관점 지향 프로그래밍을 적용한 코드를 작성할 수 있습니다. 또한, 데코레이터 패턴은 클래스를 수정하지 않고 클래스의 멤버들의 정의를 수정 및 기능을 확장할 수 있는 구조적 패턴의 하나로, 데코레이터 패턴을 사용하면 전체 기능에 신경 쓰지 않고 특정 인스턴스에 초점을 맞출 수 있습니다. 

 

[ 데코레이터 설정 ]

타입스크립트의 데코레이터는 정식으로 지원하는 문법 기능이 아닌 실험적인 기능입니다.

따라서 타입스크립트에서 데코레이터를 사용하기 위해서는 tsconfig.json 파일에서 experimentalDecorators 옵션을 활성화 해야 합니다. 

 

1
2
3
4
5
6
7
8
// tsconfig.json
{
  "compilerOptions": {
    ...
    "experimentalDecorators"true,
    ...
  }
}
cs

 

[ 데코레이터 함수 선언과 데코레이터 팩토리 ]

💡 데코레이터 함수 선언 

데코레이터를 사용하기 위해서는 데코레이터 함수를 선언해야 합니다. 데코레이터 함수는 데코레이팅된 선언( 데코레이터가 선언되는 클래스, 메서드 등)에 대한 정보와 함께 호출되는 함수여야 합니다. 

 

아래는 메서드 데코레이터의 예시이며 데코레이터 함수의 인자는 어떤 데코레이터 함수냐에 따라 다릅니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
function deco(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log('데코레이터가 평가되었습니다.');
}
 
class TestClass {
  @deco()
  test() {
    console.log('함수가 호출되었습니다.');
  }
}
 
const t = new TestClass();
t.test();
cs

 

1
2
3
4
'데코레이터가 평가되었습니다.'
 
'함수가 호출되었습니다.'
 
cs

 

💡 데코레이터 팩토리

 

데코레이터 팩토리 함수(decorator factory function)는 데코레이터 함수를 감싸는 래퍼(wrapper) 함수입니다. 보통 데코레이터가 선언에 적용되는 방식을 원하는 대로 바꾸고 싶을 때 사용됩니다.

 

프로그래밍에서 함수에게 사용자가 인자를 전달할 수 있는 것과 유사하게, 데코레이터 함수 또한 팩토리를 사용해 사용자로부터 인자를 전달 받도록 설정할 수 있습니다. 

 

즉, 데코레이터 팩토리는 사용자로부터 전달 받은 인자를, 내부에서 반환하는 데코레이터 함수는 데코레이터로 사용되는 것입니다.

 

아래 예시를 보면, 클로저 변수로 사용자 인자 값을 받고, 리턴 값으로 데코레이터 함수를 반환하여 데코레이터를 실행하는 것을 볼 수 있습니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 데코레이터 팩토리
function deco(value: string) {
  console.log('데코레이터가 평가되었습니다.');
  
  // 데코레이터 함수
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(value);
  };
}
 
class TestClass {
  // 데코레이터 팩토리를 사용하면 인자 값을 전달할 수 있다.
  @deco('HELLO WORLD')
  test() {
    console.log('함수가 호출되었습니다.');
}
 
const t = new TestClass();
t.test();
cs

 

1
2
3
데코레이터가 평가되었습니다.
HELLO WORLD
함수가 호출되었습니다.
cs

 

[ 데코레이터 합성 / 멀티 데코레이터 ]

데코레이터의 또 다른 장점으로는 하나의 멤버에 동시에 여러 개의 데코레이터를 장식할 수 있다는 점입니다. 이를 데코레이터 합성 (Decorator Composition)이라고도 부릅니다. 

 

여러 개의 데코레이터를 사용하면 수학의 합성 함수(function composition)와 같이 합성할 수 있게 되기 때문에 이렇게 불리며, 아래 데코레이터 선언의 합성 결과는 수학적으로 f(g(x))와 같습니다.

 

1
2
3
@f
@g
test
cs

 

📌 멀티 데코레이터의 실행 흐름은 다음 순으로 처리됩니다. 

1. 각 데코레이터 표현식은 위에서 아래 방향 ( ↓ ) 으로 평가(evaluate)됩니다.

2. 실행 결과는 아래에서 위로 ( ↑ ) 함수를 호출(call)합니다. 

 

데코레이터 팩토리를 사용해 멀티 데코레이터의 실행 흐름을 살펴보면 다음과 같습니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Size 데코레이터 팩토리
function Size() {
   console.log('Size(): 평가됨');
   // Size 데코레이터
   return function (target: any, prop: string, desc: PropertyDescriptor) {
      console.log('Size(): 실행됨');
   };
}
// Color 데코레이터 팩토리
function Color() {
   console.log('Color(): 평가됨');
   // Color 데코레이터
   return function (target: any, prop: string, desc: PropertyDescriptor) {
      console.log('Color(): 실행됨');
   };
}
// Button 클래스 정의
class Button {
   // 메서드에 멀티 데코레이터 적용
   @Size()
   @Color()
   isPressed() {}
}
cs

 

1
2
3
4
Size(): 평가됨
Color(): 평가됨
Color(): 실행됨
Size(): 실행됨
cs

 

@expression에서 expression 표현식을 함수로 평가하는 순서는 위에서 아래입니다.

하지만, expression이 함수로 평가된(데코레이터 팩토리) 후에, 실행 결과(데코레이터 함수)가 실행되는 순서는 아래에서 위가 됩니다.

 

[ 데코레이터 종류 ]

🧷 Class Decorator

클래스 데코레이터(class decorator)는 클래스 선언 직전에 선언되는 데코레이터입니다. 클래스 데코레이터는 클래스의 생성자의 클래스 정의(definition)를 읽거나 수정할 수 있어 기존의 클래스 정의를 확장하는 용도로 사용할 수 있습니다.

 

선언 파일(*.d.ts)과 선언 클래스(declare class) 내에서는 사용할 수 없습니다. 클래스 데코레이터 매개변수로는 클래스 생성자 자체를 받게 되는 특징이 있습니다.

 

※ 클래스 데코레이터 매개변수

  • 첫 번쨰 argument (constructor): 클래스(생성자 함수)가 전달됩니다. 타입스크립트가 클래스를 실행할 때 클래스의 생성자를 데코레이터의 constructor 파라미터로 자동 전달하므로, 생성자를 명시적으로 전달하지 않아도 됩니다.
  • 클래스 데코레이터의 리턴 값은 class 또는 void입니다.

 

💡 클래스 데코레이터 예제

아래 예시는 데코레이터가 Test의 constructor를 상속해서 추가로 프로퍼티를 지정하고 리턴해주었는데, Test 클래스의 constructor에 가서 확장이 된 것으로 생각하시면 됩니다.

 

그래서 실행 결과가 기존의 Test의 생성자에 없던 프로퍼티들이 추가된 것으로 데코레이터가 클래스의 멤버를 확장한 것입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function classDecorator<extends { new (...args: any[]): {} }>(constructor: T) {
  // Test 클래스의 constructor를 상속해서 new Test() 가 되면 추가된 생성자도 실행되도록 설정
  return class extends constructor { 
    first_prop = 'override'// 데코레이터에서 새로 프로퍼티를 덮어씌움
    new_prop = 'new property'// 데코레이터에서 새로 프로퍼티를 추가
  };
}
 
@classDecorator
class Test {
  first_prop: string;
 
  constructor(m: string) {
    this.first_prop = m;
  }
}
 
let t = new Test('abcdefg');
console.log(t);
console.log( t.first_prop ); // 'override'
 
// 데코레이터로 설정된 프로토타입 확장은 타입 단언(Type Assertion) 필요
console.log( (t as any).new_prop ); // 'new property'
cs

 

1
2
3
4
5
6
Test { 
    first_prop: 'override'
    new_prop: 'new property' 
}
override
new property
cs

 

💡 클래스 데코레이터 팩토리 사용 예제

다음은 클래스 데코레이터에 데코레이터 팩토리를 이용한 예제입니다.

데코레이터 팩토리에 전달된 사용자 인자 값을 데코레이터 함수에서 사용한 결과를 리턴합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 데코레이터 팩토리
function classDecorator(param1: string, param2: string) {
  // 데코레이터 함수
  return function <extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
      new_prop = param1;
      first_prop = param2;
    };
  };
}
 
@classDecorator('안녕하세요''반갑습니다')
class Test {
  first_prop: string;
 
  constructor(m: string) {
    this.first_prop = m;
  }
}
 
let t = new Test('world');
console.log(t);
cs

 

1
2
3
4
Test { 
    first_prop: '반갑습니다'
    new_prop: '안녕하세요' 
}
cs

 

💡 프로토타입(prototype) 이용한 확장

장식된 클래스의 constructor를 확장하는 것뿐만 아니라 프로토타입을 이용하여 확장시키는 것도 가능합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function classDecoratorFactory<extends { new (...args: any[]): {} }>(constructorFn: T) {
 
   // 프로토타입으로 새로운 프로퍼티를 추가
   constructorFn.prototype.print2 = function () {
      console.log('this is print2');
   };
   constructorFn.prototype.gender = 'male';
 
   // 클래스를 프로퍼티에 상속시켜 새로운 멤버를 추가 설정
   return class extends constructorFn {
      public name = 'zenghyun';
      private _age = 27;
 
      constructor(...args: any[]) {
         super(args);
      }
 
      public print() {
         console.log('this is print');
      }
   };
}
 
@classDecoratorFactory
class Test2 {}
 
const test2 = new Test2();
 
console.log(test2); // class_1 { name: 'zenghyun', _age: 27 }
 
// 클래스 Test의 타입에는 print 함수가 없고, 데코레이터로 동적으로 추가된 형태이니, 타입 단언을 사용
(test2 as any).print(); // this is print 
(test2 as any).print2(); // this is print2 
 
console.log((test2 as any).gender); // male
cs

 

1
2
3
4
Test2 { name'zenghyun', _age: 27 }
this is print
this is print2
male
cs

 

🧷 Method Decorator

메서드 데코레이터(method decorator)는 메서드 선언 직전에 선언되는 데코레이터로 메서드 관찰, 수정 또는 대체하는 데 사용할 수 있습니다. 

 

메서드의 속성 설명자(property descriptor)에 적용되고 메서드의 정의를 읽거나 수정할 수 있습니다. 선언 파일(*. d.ts), 오버로드 메서드(overload method), 선언 클래스에 사용할 수 없습니다. 

 

📌 참고 

Property Descriptor는 객체의 프로퍼티들을 기존보다 정교하게 정의할 수 있는 ES5의 스펙이며, 프로퍼티의 특성을 설명하는 역할을 하는 객체입니다.

이 Property Descriptor는 Object.getOwnPropertyDescriptor를 사용해서 가져올 수 있습니다.

 

 

메서드 데코레이터 함수가 전달받는 인자는 총 3가지로 다음과 같다. 

  • 첫 번째 argument: static 프로퍼티가 속한 클래스의 생성자 함수 또는 인스턴스 프로퍼티에 대한 클래스의 prototype 객체
  • 두 번째 argument: 해당 method의 이름
  • 세 번째 argument: 해당 methodproperty descriptor

 

1
2
3
4
5
6
7
function methodDecorator(
    target: any, // static 메서드라면 클래스의 생성자 함수, 인스턴스의 메서드라면 클래스의 prototype 객체
    propertyKey: string, // 메서드 이름
    descriptor: PropertyDescriptor // 메서드의 Property Descriptor
) {
    ... 
// return 값 무시됨
cs

 

메서드 데코레이터는 클래스, 메서드 이름, 호출된 메서드 (해당 메서드는 Object.defineProperty()로 만들어 짐)로 정의된 메서드 순으로 전달받습니다.

 

 

💡 메서드 데코레이터 예제 1 

만약 해당 메서드가 호출될 때 특정 무엇인가를 동작시키고 싶다면 데코레이터에서 descriptor를 다음과 같이 재정의 해주면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function methodDecorator() {
  return function (target: any, property: string, descriptor: PropertyDescriptor) {
 
    // descriptor.value는 test() 함수 자체를 가리킨다. 이 함수를 잠시 변수에 피신 시킨다.
    let originMethod = descriptor.value; 
 
    // 그리고 기존의 test() 함수의 내용을 다음과 같이 바꾼다.
    descriptor.value = function (...args: any) {
      console.log('before');
      originMethod.apply(this, args); // 위에서 변수에 피신한 함수를 call, apply, bind 를 통해 호출
      console.log('after');
    };
  };
}
 
class Test {
  property = 'property';
  hello: string;
 
  constructor(m: string) {
    this.hello = m;
  }
 
  @methodDecorator()
  test() {
    console.log('test');
  }
}
 
let test = new Test("world")
test.test()
cs

 

1
2
3
before
test
after
cs

 

데코레이터 인수의 descriptor.value로 접근하면 장식된 함수 자체로 접근하게 되는데 이를 잠시 백업하고 나중에 실행하는 식으로 응용이 가능합니다. 

 

중요한 점은 백업된 메서드를 호출할 때 apply를 이용하여 this를 바인딩해줘야 한다는 점입니다. 만일 this를 바인딩하지 않으면 해당 메서드를 어느 객체가 호출했는지 알 수 없기 때문입니다. 

 

💡 메서드 데코레이터 예제 2

좀 더 응용하자면, 메서드 데코레이터로 특정 메서드의 실행 전/후 로깅, 실행시간을 측정 가능합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function methodDecorator() {
  return function (target: any, property: string, descriptor: PropertyDescriptor) {
      
    // descriptor.value는 test() 함수 자체를 가리킨다. 이 함수를 잠시 변수에 피신 시킨다.
    let originMethod = descriptor.value;
 
    // 그리고 기존의 test() 함수의 내용을 다음과 같이 바꾼다.
    descriptor.value = function (...args: any) {
      let startTS = new Date().getTime();
 
      originMethod.apply(this, args); // 위에서 변수에 피신한 함수를 call,apply,bind 를 통해 호출
 
      let endTS = new Date().getTime();
 
      console.log(`실행시간: ${(endTS - startTS) / 1000} S`);
    };
  };
}
 
// ...
cs

 

1
2
3
test
실행시간: 0 S
 
cs

 

🧷 Accessor Decorator

접근자 데코레이터(accessor decorator)는 접근자(accessor) 바로 앞에 선언합니다. 접근자의 속성 설명자에 적용되고 접근자의 정의를 읽거나 수정할 수 있다. 선언 파일(*. d.ts)과 선언 클래스에는 사용할 수 없습니다.

 

※ 접근자 (accessor)

객체 프로퍼티를 객체 외에서 읽고 쓸 수 있는 함수이다. 쉽게 말하자면 getter와 setter를 뜻하며, 타입스크립트에서는 getter, setter를 구현할 수 있는 get, set 키워드가 있습니다.

 

📌 접근자 데코레이터 매개변수 

  • 첫 번째 argument: static 프로퍼티가 속한 클래스의 생성자 함수 또는 인스턴스 프로퍼티에 대한 클래스의 prototype 객체 
  • 두 번째 argument: 해당 method의 이름
  • 세 번째 argument: 해당 method의 property descriptor 

📌 접근자 데코레이터 리턴 값

  • Property Descriptor 형태
  • void

💡 접근자 데코레이터 예제 1

특정 프로퍼티가 열거가 가능할지 결정하는 데코레이터 예제입니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function Enumerable(enumerable: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.enumerable = enumerable;
  };
}
 
class Person {
  constructor(private name: string) {}
  
  @Enumberable(true)
  get getName() {
    return this.name;
  }
  
  @Enumberable(false)
  set setName() {
    this.name = name;
  }
}
 
const person = new Person('hello');
for (let key in person) {
  console.log(`${key}: ${person[key]}`);
}
cs

결과를 출력하면 getName은 출력되지만 setName은 열거하지 못하게 되었기 때문에 for문에서 key로 받을 수 없습니다.

 

1
2
name: hello
getName: hello
cs

 

🧷 Property Decorators

속성 데코레이터(property decorator)는 클래스의 프로퍼티 선언 바로 전에 선언됩니다.

속성 데코레이터는 메서드 데코레이터와 다르게 데코레이터 함수에 Property Descriptor가 인자로서 제공되지 않는다는 차이가 있습니다. 대신에 속성 데코레이터도 마찬가지로 Property Descriptor 형식의 객체를 반환해서 프로퍼티의 설정을 바꿀 수 있습니다.

 

📌 속성 데코레이터 매개변수

  •  첫 번째 argument: static 프로퍼티라면 클래스의 생성자 함수, 인스턴스 프로퍼티라면 클래스의 prototype 객체
  •  두 번째 argument: 해당 property의 이름

📌 속성 데코레이터 리턴 값

  • Property Descriptor 형태
  • void
1
2
3
4
5
6
function propertyDecorator(
  target: any, // static 프로퍼티라면 클래스의 생성자 함수, 인스턴스 프로퍼티라면 클래스의 prototype 객체
  propertyName: string, // 프로퍼티 이름
): any {
    ...
// return하는 값이 Property Descriptor 형태 또는 void. 이로서 해당 property의 writable 등을 조작할 수 있음
cs

 

💡 속성 데코레이터 예제 

리턴 값으로 Object.defineProperty()를 반환함으로써, 이를 통해 속성의 부가적인 설정을 할 수 있습니다.

 

예를 들어 다음과 같이, 앞의 데코레이터는 boolean 타입의 인자를 전달받아 writable로 설정하게 되는데 writable이 false일 경우 해당 속성은 값을 수정할 수 없게 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function writable(isWritable: boolean) {
  return function (target: any, propertyName: any): any {
    return {
      writable,
    };
  };
}
 
class Test {
  property = 'property';
 
  @writable(false)
  public data1 = 0;
 
  @writable(true)
  public data2 = 0;
}
 
const t = new Test();
t.data1 = 1000;
t.data2 = 1000// 런타임 에러 !! - data2는 writable이 false라서 값을 대입할 수가 없다.
 
cs

 

💡 속성 데코레이터 getter, setter 설정 예제 

좀 더 응용하자면 다음과 같이 getter와 setter도 설정이 가능합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function SetDefaultValue(numberA: number, numberB: number) {
  return (target: any, propertyKey: string) => {
    const addNumber = numberA * numberB;
    let value = 0;
 
    // 데코레이터가 장식된 DataDefaultType의 num 이라는 프로퍼티의 객체 getter / setter 설정을 추가한다.
    Object.defineProperty(target, propertyKey, {
      get() {
        return value + addNumber; // 조회 할때는 더하기 시킴
      },
      set(newValue: any) {
        value = newValue - 30// 설정 할때는 30을 뺌
      },
    });
  };
}
 
class DataDefaultType {
  @SetDefaultValue(1020)
  num: number = 0;
}
 
const test = new DataDefaultType();
 
test.num = 30;
console.log(`num is 30, 결과 : ${test.num}`); // num is 30, 결과 : 200
 
test.num = 130;
console.log(`num is 130, 결과 : ${test.num}`); // num is 130, 결과 : 300
cs

 

1
2
3
num is 30, 결과 : 200
num is 130, 결과 : 300
 
cs

 

🧷 Parameter Decorators

매개변수 데코레이터(parameter decorator)는 생성자 또는 메서드의 매개 변수에 선언되어 적용됩니다. 데코레이터는 가로로 써도 인식되기 때문에 함수의 매개변수 왼쪽 옆에 명시해 주면 됩니다. 선언 파일(*. d.ts), 선언 클래스에서는 사용할 수 없습니다. 

 

📌 파라미터 데코레이터 매개변수

  • 첫 번째 argument: static 프로퍼티가 속한 클래스의 생성자 함수 또는 인스턴스 프로퍼티가 속한 클래스의 prototype 객체
  • 두 번째 argument: 매개변수가 들어있는 method의 이름
  • 세 번째 argument: 메서드 파라미터 목록에서의 index
1
2
3
4
5
6
7
function parameterDecorator(
  target: any, // static 메서드의 파라미터 데코레이터라면 클래스의 생성자 함수, 인스턴스의 메서드라면 prototype 객체
  methodName: string, // 매개변수가 들어있는 메서드의 이름
  paramIndex: number // 매개변수의 순서 인덱스
) {
    ...
// 리턴값은 무시됨
cs

 

💡 매개 변수 데코레이터 예제 

아래 예제는 제대로 된 값이 전달되었는지 확인하는 데코레이터입니다. 매개 변수 데코레이터는 단독으로 사용하기보다는 메서드 데코레이터와 함께 사용할 때 유용하게 사용됩니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { BadRequestException } from '@nestjs/common';
 
// 매개 변수 데코레이터 함수
// target 클래스의 validators 속성에 유효성을 검사하는 함수 할당
function MinLength(min: number) {
  return function(target: any, propertyKey: string, parameterIndex: number) {
    target.validators = {
      minLength: function(args: string[]) {
        return args[parameterIndex].length >= min;
      }
    }
  }
}
 
// 메서드 데코레이터 함수
function Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const method = descriptor.value;
  
  // 설명자의 value에 유효성 검사 로직이 추가된 함수를 할당
  descriptor.value = function(...args) {
    // target에 저장해둔 validators를 모두 수행한다. 이때 원래 메서드에 전달된 인수들을 각 validator에 전달한다.
    Object.keys(target.validators).forEach(key => {
      if (!target.validators[key](args)) {
        throw new BadRequestException();
      }
    })
    // 기존 함수를 실행
    method.apply(this, args);
  }
}
 
class User {
  private name: string;
  
  @Validate
  setName(@MinLength(3name: string) {
    this.name = name;
  }
}
 
const t = new User();
t.setName('hello');
console.log('---------------');
t.setName('hi');    // BadRequestException
cs

 

[ 데코레이터 요약 및 호출 순서 ]

각 데코레이터의 특징을 간략하게 정리하면 다음과 같습니다. 

 

데코레이터 역할 호출 시 전달되는 인수 선언 불가능한 위치 
클래스 데코레이터 클래스의 정의를 읽거나 수정 constructor .d.ts 파일, declare 클래스
메서드 데코레이터 메서드의 정의를 읽거나 수정 target, propertyKey,
propertyDescriptor
.d.ts 파일, declare 클래스, 오버로드 메서드
접근자 데코레이터 접근자의 정의를 읽거나 수정 target, propertyKey,
propertyDescriptor
.d.ts 파일, declare 클래스
속성 데코레이터 속성의 정의를 읽음 target, propertyKey .d.ts 파일, declare 클래스
매개변수 데코레이터  매개변수의 정의를 읽음 target, proertyKey,
parameterIndex
.d.ts 파일, declare 클래스

 

 

[ 참고 자료 ]

Comments