메서드 데커레이터는 이름과 같이 메서드 앞에서 선언되는 데커레이터이다.
이 데커레이터는 메서드의 속성 설명자(속성의 특성을 설명하는 객체, propertyDescriptor)에 적용되고 메서드의 정의를 읽거나 수정할 수 있다.
메서드 데커레이터는 다음 세개를 인수로 갖는다.
- 정적 멤버가 속한 클래스의 생성자 함수이거나 인스턴스 멤버에 대한 클래스의 프로토타입
- 멤버의 이름
- 멤버의 속성 설명자. ECMA Script에서 지원하는 표준 데커레이터의 PropertyDescriptor 타입을 확장한 것을 사용
타입스크립트에서는 다음과 같이 PropertyDescriptor를 선언하고 있다.
interface PropertyDescriptor { configurable?: boolean;//속성의 정의를 수정할 수 있는 지에 대한 여부 enumerable?: boolean;//열거형인지 여부 value?: any;//속성 값 writable?: boolean;//수정 가능 여부 get?(): any;//getter set?(v: any): void;//setter }
위 내용만으로는 잘 와닿지 않으니 예시 코드를 통해서 알아보자.
function HandleError() {
return function(target: any, propertyKey: string, descriptor: propertyDescriptor) {
console.log(target);
console.log(propertyKey);
console.log(descriptor);
const method = descriptor.value;
descriptor.value = function() {
try {
method();
} catch (e) {
//에러 핸들링 로직 구현//
console.log(e);
}
}
};
}
class Greeter {
@HandleError
hello() {
throw new Error('test error');
}
}
const t = new Greeter();
t.hello();
function(target: any, propertyKey: string, descriptor: propertyDescriptor)
우선 이 라인에서 HandleError 함수는 위에서 언급한 세가지의 인수를 갖는 함수를 반환하는 함수 임을 알 수 있다.
const method = descriptor.value; // descriptor.value = function() { try { method(); } catch (e) { console.log(e); } }
첫 라인은 설명자의 value 속성으로 원래 정의된 메서드를 저장한다.
그 다음은 설명자의 value를 재정의 하는데 try 구문 안에서 기존의 메서드를 호출한다.
이런식으로 코드를 작성하는 이유는 예외 처리와 관련이 있다고 하는데, 기존의 함수는 예외나 에러가 생길 경우 그 문제를 다룰 방법이 없는데, 바뀐 함수는 원본 함수를 호출하되 함수가 에러나 예외를 던질 경우 그 예외를 콘솔에 로깅하는 방식으로 동작을 수정한 것이다.
이는 프로그램의 안정성을 높이고, 디버깅에 도움이 되는 정보를 제공하는 데 도움이 될 수 있다. 또한 예외를 제외한 부분에서는 정상작동을 할 수 있도록 하는 것이다.
@HandleError() hello() { throw new Error('test error'); }
다른 데커레이터들과 마찬가지의 방식으로 메서드의 정의를 읽거나 수정한다.
이 예시만으로는 정확히 어떤 역할들을 하는지 모르겠지만, 대략적으로는 예외처리를 하거나 메서드를 호출 할 때 특정 행동을 동작시키고 싶으면 데커레이터로 조작해주면 되는 것 같다..
이 포스트는 위 책을 기반으로 작성하고 있습니다...