[TypeScript] Decorator

Posted by 신희준 on November 1, 2017


타입스크립트 코리아 이웅재님의 강의 참조


2017 - 11 - 01 (수)

  • Class Decorator
  • Method Decorator
  • Property Decorator
  • Parameter Decorator

  • Decorator 초기 셋팅

    • 프로젝트 생성
      • $ mkdir ts-decorator
      • $ cd ts-decorator
      • $ yarn init -y
    • typescript 설치
      • $ yarn add typescript -d
    • tsconfig 설정
      • $ node_modules/.bin/tsc –init (tsconfig 파일 생성)
      • tsconfig 에서 experimentalDecorators 주석 해제
      • tsconfig 에서 outdir을 주석 해제 후 dist로 준다.
    • test.ts 파일 하나 생성

    • vscode 컴파일 설정
      • ctrl + shift + b 로 compile 설정 변경
      • {workspaceRoot}/node_modules/.bin/tsc
      • ctrl + shift + b 로 compile


    Class Decorator ( 모든 데코레이터는 function 임 )


    function hello(constructorFn: Function){
        console.log(constructorFn)
    }
    
    function helloFactory(show: boolean){
        if(show){
        return hello;
        }else{
            return null;
        }
    
    }
    
    @helloFactory(true)
    class Person{
    
    }
    
    //ctrl + shift +b (컴파일)
    //node dist/test.js 실행시 결과 : [Function: Person]
    
    function hello(constructFn: Function){
        constructFn.prototype.hello = function(){
            console.log('hello');
        }
    }
    
    
    @hello
    class Person{
    
    }
    
    const p = new Person();
    (<any>p).hello();
    //hello 출력
    


    Method 데코레이터


    function hello(constructFn: Function){
        constructFn.prototype.hello = function(){
            console.log('hello');
        }
    }
    
    function editable(canBeEditable : boolean){
        return function(target: any, propName: string, description : PropertyDescriptor){
            console.log(target)// 출력 : Person {}
            console.log(propName) // 출력 : hello
            console.log(description)
            /* description 출력결과
            { value: [Function: hello],
              writable: true,
              enumerable: false,
              configurable: true }
    
            */
            description.writable = canBeEditable;
        }
    }
    
    class Person{
        constructor(){
            console.log('hello')
        }
    
        @editable(false)
        hello(){
            console.log('hello')
        }
    }
    
    
    const p = new Person();
    p.hello()
    p.hello = function(){
        console.log('world');
    }
    
    p.hello();
    


    property Decorator


    function writable(canBewritable: boolean){
        //target은 있으나 description이 없음
        return function(target : any, propName : string):any {
            console.log(target); // Person{} 출력
            console.log(propName); // Person 의 속성명이 나옴
    
    
            return{
                writable: canBewritable
            };
        }
    }
    
    
    class Person{
       @writable(true) // false 가 되면 에러가 남
        name : string = 'shj';
            constructor(){
                console.log('new Person()')
            }
    
    }
    
    
    const p = new Person();
    console.log(p.name)
    


    parameter Decorator


    function print(target: any, methodName : string, paramIndex: number){
        console.log(target) // person{}
        console.log(methodName) // hello
        console.log(paramIndex) // 0
    
    }
    
    
    class Person{
        private _name : string;
        private _age: number;
    //age 필드에 @print 데코레이터 추가
        constructor(name: string, @print age: number){
            this._name = name;
            this._age = age;
        }
    //@message 에  @print 데코레이터 추가
        hello(@print message: string){
            console.log(message);
        }
    
    }
    
    



    • class decorator , method decorator , property decorator, parameter decorator 모두 데코레이터를 구현하는 메서드의 시그니쳐(매개 변수 비슷한 듯)가 다르다. 그러므로 잘 알아둘 필요가 있다고 한다.