본문 바로가기
TypeScript

Decorator

by eddypark 2023. 8. 30.

- 클래스 선언과 멤버에 대한 주석(annotations)과 메타 프로그래밍 구문을 모두 추가할 수 있는 방법이다.

- 데코레이터를 사용하려면 tsconfig.json설정에서 experimentalDecorators를 true로 바꿔줘야 한다.

- 클래스, 속성, 메서드, 접근 제어자, 매개변수 등에 사용할 수 있는 특별한 종류의 선언이다. @를 키워드로 붙인다.

- 데코레이터가 적용된 메서드가 실행되거나 클래스가 new라는 키워드를 통해 인스턴스화 될 때가 아닌 런타임 때 실행된다. 즉, 매번 실행되지 않는다.

 

(1) 프로퍼티 데코레이터

- 프로퍼티 선언 직전에 선언한다.

- 특정 이름의 프로퍼티가 클래스에 선언되었음을 관찰하는데만 사용한다.

class a {
    @b
    c = 'wangi';
}
 
const d = new a();
console.log(d.c);                      // eddy
                                       // wangi
 
function b() {   // @b에 대한 함수 선언
    console.log('eddy');
}

 

(2) 메소드 데코레이터

- 메소드 선언 직전에 선언한다.

- 프로퍼티 설명자에 적용되며 메서드 정의를 관찰, 수정 또는 대체하는 데 사용한다.

function b(isEditable: boolean) {
    return function(target: any, propName: string, description: PropertyDescriptor) {
        console.log(target);      // a { }
        console.log(propName);    // c
        console.log(description); //{  "writable": true,  "enumerable": false,  "configurable": true} 

        description.writable = isEditable;
    }
}

class a {
    constructor() {
        console.log("hello");
    }

    @b(false)
    c() {
        console.log("wangi");
    }
}

const d = new a();
d.c();                    // hello
                          // wangi
d.c = function() {
    console.log("eddy");  // 변경안됨
}
d.c();                    // wangi

 

(3) 클래스 데코레이터

- 클래스 선언 직전에 선언한다.

- 클래스 생성자에 적용되며 클래스 정의를 관찰, 수정 또는 교체하는 데 사용한다.

@b
class a {
    x: string;
    constructor(y: string) {
        this.x = y;
    }
}
 
function b<T extends {new(...args:any[]):{}}>(constructor:T) {
    return class extends constructor {
        z = "eddy";
    }
}
 
const c = new a("wangi");
console.log(c);          // {  "x": "wangi", "z": "eddy"  }

 

(4) 데코레이터 팩토리

- 데코레이터가 선언에 적용되는 방식을 원하는 대로 바꾸고 싶을 때 데코레이터 팩토리 작성한다.

function b(x : string) {            // 데코레이터 팩토리
    console.log(x);
    return function(target, name) { // 데코레이터 함수
        console.log('wangi');
    }
}
 
class a {
    @b(26)       // 데코레이터 팩토리를 사용하여 값 전달 가능
    y = 'eddy';
}
 
console.log('인스턴스가 만들어지기 전');
console.log(new a());
// 결과
// 26
// wangi
// 인스턴스가 만들어지기 전
// a: {"y": "eddy"}

'TypeScript' 카테고리의 다른 글

타입 앨리어스  (0) 2023.09.04
Generic  (0) 2023.09.01
Module  (0) 2023.08.31
Class  (0) 2023.08.30
TypeScript란?  (0) 2023.08.30