class
및 class
내부에서만 사용할 수 있다. 즉, class
, class 내부의 property, accessor, method 그리고 parameter에 사용할 수 있다는 말 !
function
runtime
에 호출됨 (class instance를 생성하지 않아도 호출됨)클래스의 생성자를 유일한 인수로 호출하며, 클래스의 프로퍼티를 변경하는 데코레이터이다.
Car(name, price) {
this.name = name;
this.price = price;
}
function CustomDecorator(constructor: any) {
console.log(constructor);
return <any>class extends constructor {
name = 'SM6';
color = 'black';
}
}
function ClassDecorator2(param: any) {
console.log(param);
return function(constructor: any) {
console.log(constructor);
return <any>class extends constructor {
someValue = param.someValue + ' world!';
}
}
}
이렇게 아래처럼 사용할 수 있다.
@ClassDecorator2({someValue: 'hello!'})
class Car {
name: string;
...
3가지 argument를 받는다.
✏️ method에서의 property descriptor ✏️
value: 현재 값 value
writable: 수정 가능하면 true
enumarable: for (i in [1,2,3])처럼 순회가 가능하면 true
configurable: Property definition이 수정 및 삭제가 가능하면 true
class A {
b: string = "Hello"
get c(): string {
return `${this.b} World!`
}
@LogError("에러가 발생했습니다!")
d(e: string): void {
console.log(e)
throw new Error()
}
}
위 class A의 메서드인 d()에 @LogError
라는 decorator를 한 번 만들어보자.
@LogError
는 d() 메서드에서 error 발생 시 핸들링할 수 있도록 만드는 decorator이다.
function LogError(errorMessage: string) {
return function (target: any, key: string, desc: PropertyDescriptor): void {
const method = desc.value
desc.value = function (e: string) {
try {
method(e)
} catch (err) {
console.log(errorMessage)
}
}
}
}
위 코드가 바로 @LogError
를 구현한 코드이다.
인자 값으로custom errorMessage
를 받아 error가 발생하면 console에 출력하도록 했다.
좀 더 발전시켜, Parameter로 errorMessage 대신, function을 넘겼다면 해당 function을 호출하도록 만들 수도 있다.
3가지 argument를 받는다.
class A {
b: string = "Hello"
get c(): string {
return `${this.b} World!`
}
d(
@ParameterDecorator e: string,
@ParameterDecorator f: string,
@ParameterDecorator g: string
): void {
console.log(e, f, g)
}
}
아래는 ParameterDecorator를 구현한 코드이다.
function ParameterDecorator(target: any, key: string, index: number) {
console.log(target)
console.log(key)
console.log(index)
}
실행 결과는 다음과 같다.
{ c: [Getter], d: [Function (anonymous)] }
d
2
{ c: [Getter], d: [Function (anonymous)] }
d
1
{ c: [Getter], d: [Function (anonymous)] }
d
0
나머지 property decorator
, accessor decorator
는 모두 이와 유사하다고 한다.
실제 이런 유용한 코드를 짜기 위해서는 reflect-metadata
라는 라이브러리를 사용해야 한다.
특정 타입에 대한 metadata를 내보낼 수 있도록 tsconfig.json
파일에 emitDecoratorMetadata compiler options
를 추가하자..!
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
참고