본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


TypeScript

타입스크립트 데코레이터(Typescript Decorator)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 7. 5.

타입스크립트를 활용하여 만나보는 데코레이터(Decorator) 입니다.

앵귤러(Angular)를 활용하여 개발을 하다 보면 자주 만나는 기능이라 사실 앵귤러 환경에서만 지원되는 기능이라 생각 했었는데 타입스크립트에서 지원하는 기능인 줄 몰랐었습니다.

이래서 사람은 역시 공부를 깊게 해야되는가 봅니다..

* 기본적인 타입스크립트 개발환경을 알아야 합니다.

 

데코레이터는 자바의 에노테이션과 비슷한 느낌이 드는 기능으로, 데코레이터가 붙은 클래스, 메소드(함수) 및 변수 등에 데코레이터에서 정의된 기능이 동작하는 것을 의미 합니다.

아래 클래스 형태의 데코레이터가 적용 된 타입스크립트 코드를 살펴 보겠습니다.

* 클래스에 적용하기, 파일 이름 : index.ts

function whoAmI(target : Function) : void{
    console.log(`your function : ${target}`)
}

@whoAmI
class Friend{
    constructor(){

    }
}

let test = new Friend()

 

whoAmI라는 데코레이터를 통해서 Friend 클래스의 생성자를 출력하게 하였습니다.

이를 컴파일 후에 테스트를 하려 해 보았으나 아래와 같은 문제를 만나게 되었습니다.

오류..? 경고...?

 

해당 빨강색 밑줄은 일종의 경고(warning)입니다.

내용은 "데코레이터에 대한 실험적 지원 기능은 이후 릴리스에서 변경될 수 있습니다." 라고 나오며 타입스크립트 설정을 조금만 수정 해 주면 쉽게 해결 가능합니다.

먼저 tsconfig.json파일에서 아래처럼 experimentalDecorators 값을 true로 추가하여 줍니다.

* 이름 : tsconfig.json

설정 내용은 다소 다를수 있겠습니다.

 

그리고 VS코드를 사용 중 이라면 설정탭에서의 jsconfig.json 또는 tsconfig.json 파일에 대한 설정을 재 정의 한다는 것에 대해서 체크를 해 줍니다.

이미 체크가 되어 있으면 상관 없습니다.

 

여기까지 하였다면 오류는 사라지고 이제 컴파일을 할 수 있게 됩니다.

이제 컴파일 후 실행을 하여 보도록 합니다.

* 컴파일: tsc --project tsconfig.json

* 실행 : node index.js

오~ 잘 나옵니다!!

 

생성자의 내용이 잘 출력이 되었지만..

이것만 가지고서는 데코레이터를 사용해야되는 이유가 잘 이해되지 않으므로 아래 메소드 형태의 데코레이터를 살펴 보겠습니다.

index.ts파일을 메소드 형태의 데코레이터로 수정하여 보았습니다.

* 메소드에 적용하기, 파일 이름 : index.ts

function todo(target: any, prop: string, desc: PropertyDescriptor) {
    let originMethod = desc.value
    desc.value = function (...args: any[]) {
        console.log("2. 함수 동작전 : " + prop)
        let result = originMethod.apply(this, args)
        console.log("4. 함수 동작후 : " + prop)
        return result
    }
}

class Task {
    @todo
    runTask(arg: any): any {
        console.log('3.함수 동작 : '+arg)
        return "끝"

    }
}

let task = new Task();
console.log("1. 클래스 생성 후 함수 호출 시작 ")
let result = task.runTask("param")
console.log("5. 결과 : " + result);

 

todo라는 데코레이터는 메소드 형태의 데코레이터의 동작 구분을 보여 줍니다.

내부의 3개의 변수는 옵셔널(Optional)형태입니다.

 - target은 적용된 대상을 의미합니다. 메소드인 경우 메소드를 표시, 클래스이면 클래스를 표시 합니다.

 - prop은 적용된 대상의 이름의 문자값을 의미 합니다.

 - desc는 속성을 의미 합니다.

 

클래스 내부의 메소드에 대한 세부행동이 어떻게 동작하는지 잘 볼 수가 있습니다.

메소드 동작 전, 중, 후에 대한 행위를 만들 수 있으므로 다양한 기능을 만들 수 있을 것 같습니다.

마치 인터셉터같네요!

 

이번에는 메소드가 아닌 변수에 데코레이터를 붙이는 방식 입니다.

변수에 데이터가 대입되는 경우 데코레이터를 통해서 값을 바꾸어 줄 수 있습니다.

아래 소스코드를 보면 데코레이터에서 기본값을 받아서 적용하는 모습을 볼 수 있습니다.

* 변수에 적용하기, 파일 이름 : index.ts

function SetDefaultValue(numberA : number, numberB : number) {
    return(target : any, propertyKey : string | symbol) => {
        const addNumber = numberA * numberB
        let value = 0
        Object.defineProperty(target, propertyKey, {  //PropertyDescriptor에 대한 재 정의
            get() {
                return value + addNumber
            },
            set(newValue : any) {
                value = newValue
            }
        })
    }
}


class DataDefaultType {
    @SetDefaultValue(10, 20)
    num : number
}

const test = new DataDefaultType()
test.num = 30
console.log(`num is 30, 결과 : ${test.num}`)
test.num = 130;
console.log(`num is 130, 결과 : ${test.num}`)

 

위 코드를 실행하면 대입 연산자에 의해서 30, 130이라는 값이 변수 num에 대입되지만 실제로 출력되는 값은 10과 20이 곱해져서 더해진 값이 나오게 됩니다.

변수에 값이 대입되면 해당 값 자체가 정의된 계산방법에 의해서 바뀌는 것을 볼 수 있습니다.

변수에 대한 데코레이터로 값을 이렇게 설정 할 수 있습니다.

 

클래스, 메소드 및 변수에 데코레이터를 적용하는 방법에 대해서 살펴 보았습니다.

데코레이터와 관련된 내용에서 PropertyDescriptor 객체(인터페이스)가 자주 언급되며 사용되는 것을 볼 수 있습니다.

애노테이션을 이루는 기본적인 타입과 내부에서의 자료형으로 쓰이는 인터페이스를 잘 알아 두면 좀더 다양한 기능을 사용할 수 있을 것 같습니다.

PropertyDescriptor에 대해서 좀 더 알아볼 필요가 있겠습니다.

 

앵귤러에서는 자주 볼 수 있지만 데코레이터를 활용한 개발 방법은 아직까지는 많이 사용되지는 않는 것 같습니다.

좀더 깔끔한 코드를 만들기 위해서는 타입스크립트에서 제공하는 데코레이터에 대해서 살펴보는 것은 어떨까요..? : )

 

이상으로 타입스크립트 데코레이터(Typescript Decorator)에 대해서 살펴 보았습니다.

 

위 내용은 영진닷컴에서 제공한 "단숨에 배우는 타입스크립트" 책을 지원 받아 참고하여 작성한 포스팅 입니다.

내용이 쉽지가 않아 가볍게 한번 훓고난 뒤에 천천히 보시는 것을 추천드립니다.

기타 문의사항 또는 궁금한점은 메일 또는 댓글로 연락주세요.👻

 

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글