NOTE
- Object.defineProperty()를 통해 멤버 재정의를 수행하는 필드 데코레이터는 static 멤버에 대해서 제대로 동작한다. 인스턴스 멤버에는 의도대로 동작하지 않음
- 데코레이터 적용 순서는 아래(오른쪽)부터 우선, 위쪽(왼쪽)으로 차례대로 적용
타입 참고
type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
[1] 클래스
[2] 필드
[3] 메소드
[4] 파라미터