데코레이터는 클래스, 속성, 메서드, 접근 제어자, 매개변수 등에 사용할 수 있는 특별한 함수이다. 데코레이터는 메타 프로그래밍 하는데 유용하게 사용될 수 있다. 클래스에 사용되는 데코레이터 함수의 인자로 주어지는 값은 class의 구현부 전체이다.
"experimentalDecorators": true,
/* Enable experimental support for legacy experimental decorators. */
function Logger(constructor: Function) {
console.log("Logger!");
}
@Logger
class Person {
name = "otter";
constructor() {
console.log("Creating Person object...");
}
}
// const ott = new Person();
데코레이터 팩토리 함수란 데고레이터 함수를 감싸는 래퍼 함수이다. 데코레이터 팩토리 함수는 인자를 받을 수 있고 반환 값을 익명함수로 하여 데코레이터 함수를 반환한다.
데코레이터 팩토리 함수를 이용하면, 인자를 전달해 줄 수 있어 데코레이션 함수의 기능을 더 풍부하게 할 수 있다.
function Logger(c: string) { // 데코레이터 팩토리 함수의 parameter가 주어진다.
// console.log("Logger!");
return function (constructor: Function) {
console.log("Logger!");
console.log(constructor); // 테코레이터 함수의 인자
console.log(c); // 데코레이터 팩토리 함수에서 전달되는 인자
};
}
@Logger("test~~")
class Person {
name = "otter";
constructor() {
console.log("Creating Person object...");
}
}
// const ott = new Person();
function WithTemplate(template: string, hookId: string) {
return function (constructor: any) {
const hookEl = document.getElementById(hookId); // 두번째 인자로 주어진 HTML El의 ID로 DOM에 접근
const p = new constructor();
if (hookEl) {
hookEl.innerHTML = template; // 첫번째 인자로 주어진 템플릿을 두번째 인자로 주어진 HTML El안에 삽입
hookEl.querySelector("h1")!.textContent = p.name;
}
};
}
@WithTemplate("<h1>My Person Object</h1>", "app")
class Person {
name = "Max";
constructor() {
console.log("Creating person object...");
}
}
const pers = new Person();
console.log(pers);
만약 다음과 같이 클래스 데코레이터 함수를 반환하는 데코레이터 팩토리가 사용되고 있다고 생각해보자.
@DecoratorFactory1
@Decorator2
@DecoratorFactory3
Class ClassName {
...
}
이럴 경우 실행 순서는 아래와 같다.
@Decorator1("1") // Factory
@Decorator3
@Decorator2("2") // Factory
class SomeClass {
constructor() {
console.log("creating object");
}
}