[TypeScript] 데코레이터, Decorator

jm4293·2024년 2월 12일
0
  • 데코레이터는 타입스크립트에서도 실험적인 기능으로써 사용할 수 있기 때문에 커맨드 라인이나 tsconfig.json 에서 experimentalDecorators 옵션을 추가해야한다.
// tsconfig.json
{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}

데코레이터 이란

  • 데코레이터는 클래스, 속성, 메서드, 접근 제어자, 매개변수 등에 사용할 수 있는 특별한 함수이다. 선언된 데코레이터 함수를 사용할 때는 데코레이터 이름 앞에 @를 붙입니다.
  • 데코레이터는 앞에서 말한 것처럼 "클래스", "메서드", "접근자", "프로퍼티", "파라미터"에 적용할 수 있습니다. 데코레이터는 @expression 형식으로 적용하는데, 여기에서 expression 은 반드시 함수여야 합니다.
function fistDecorator(target, name) {
    console.log('fistDecorator');
}

class Person {
    @fistDecorator
    job = 'programmer';
}

const p = new Person();
console.log(p.job);

// 실행결과
// 1. fistDecorator
// 2. programmer

데코레이터 팩토리

  • 함수 사용 시, 사용자가 인자를 전달할 수 있는 것과 유사하게, 데코레이터 함수 또한 팩토리를 사용해 사용자로부터 인자를 전달 받도록 설정할 수 있다. 데코레이터 팩토리 함수는 데코레이터 함수를 감싸는 래퍼 함수이다. 팩토리는 사용자로부터 전달 받은 인자를, 내부에서 반환되는 데코레이터 함수는 데코레이터로 사용된다.
  • 위의 예제에서 @firstDecorator 데코레이터를 일반화해서 조금 더 다양한 상황에서 사용할 수 있도록 파라미터를 전달해야 할 수도 있습니다. 그러면 데코레이터 함수를 생성하는 함수인 데코레이터 팩토리를 작성하면 됩니다.
  • 실행 결과를 살펴보면 데코레이터는 클래스를 인스턴스화하기 위해 클래스를 호출하기 전에 실행됩니다.
function firstDecorator(param) {
    console.log('factory’);
    return function(target, name) {
        console.log('decorator');
    }
}

class SomeClass {
    @firstDecorator(123)
    prop = ‘a';
}

console.log('인스턴스가 만들어지기 전');
console.log(new SomeClass());

// 실행결과
// 1. factory
// 2. decorator
// 3. 인스턴스가 만들어지기 전

데코레이터 여러개 적용

  • @expression 에서 expression 표현식을 함수로 평가하는 순서는 "위에서 아래"입니다. 실행결과에서 "decoA factory" , "decoC factory" 만 출력되고 "decoB decorator" 가 출력되지 않은 이유는 @decoB 는 팩토리 함수가 없기 때문입니다.
  • expression 이 함수로 평가된 후에 데코레이터 함수가 실행되는 순서는 "아래에서 위"입니다. 여기에서 말하는 데코레이터 함수란 @decoA, @decoC의 경우에는 팩토리 함수에서 반환하는 익명 함수이고, @decoB의 경우에는 decoB 함수입니다.
function decoA(param) {
    console.log('decoA factory');
    return function(target, name) {
        console.log('decyA decorator')
    }
}

function decoB(target, name) {
    console.log('decoB decorator');
}

function decoC(param) {
    console.log('decoC factory');
    return function(target, name) {
        console.log('decoC decorator');
    }
}

class SomeClass {
    @decoA(1)
    @decoB
    @decoC(2)
    prop = 1;
}

// 실행결과
// 1. decoA factory
// 2. decoC factory
// 3. decoC decorator
// 4. decoB decorator
// 5. decoA decorator
profile
무언가를 만드는 것을 좋아합니다

0개의 댓글

관련 채용 정보