반응형
JTS는 모든 메소드에 데코레이터 적용 / 클래스 메소드 열거
클래스 내의 모든 메소드에 데코레이터 기능을 적용하여 다음을 대체하고 싶습니다.
class User {
@log
delete() {}
@log
create() {}
@log
update() {}
}
와 함께
@log
class User {
delete() {}
create() {}
update() {}
}
클래스 장식자를 만들고 대상의 프로토타입에 속성을 열거합니다.
각 속성에 대해:
- 속성 설명자를 가져옵니다.
- 방법을 위한 것인지 확인합니다.
- 메서드 호출에 대한 정보를 기록하는 새 함수로 설명자 값을 래핑합니다.
- 수정된 속성 설명자를 다시 속성으로 재정의합니다.
특성 설명자를 수정하는 다른 장식자와 함께 사용할 수 있도록 하려면 특성 설명자를 수정하는 것이 중요합니다.
function log(target: Function) {
for (const propertyName of Object.keys(target.prototype)) {
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyName);
const isMethod = descriptor.value instanceof Function;
if (!isMethod)
continue;
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
const result = originalMethod.apply(this, args);
console.log("The return value is: " + result);
return result;
};
Object.defineProperty(target.prototype, propertyName, descriptor);
}
}
기본 클래스 메서드
이것이 기본 클래스 메서드에도 영향을 미치도록 하려면 다음과 같은 방법을 사용해야 합니다.
function log(target: Function) {
for (const propertyName in target.prototype) {
const propertyValue = target.prototype[propertyName];
const isMethod = propertyValue instanceof Function;
if (!isMethod)
continue;
const descriptor = getMethodDescriptor(propertyName);
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
const result = originalMethod.apply(this, args);
console.log("The return value is: " + result);
return result;
};
Object.defineProperty(target.prototype, propertyName, descriptor);
}
function getMethodDescriptor(propertyName: string): TypedPropertyDescriptor<any> {
if (target.prototype.hasOwnProperty(propertyName))
return Object.getOwnPropertyDescriptor(target.prototype, propertyName);
// create a new property descriptor for the base class' method
return {
configurable: true,
enumerable: true,
writable: true,
value: target.prototype[propertyName]
};
}
}
앞으로 이 문제를 해결하지 못할 경우:
저는 데이비드의 대답에 영감을 받아 저만의 버전을 만들었습니다.저는 나중에 그것을 npm 패키지로 만들었습니다: https://www.npmjs.com/package/decorate-all
OP의 시나리오에서, 이것은 다음과 같이 사용될 것입니다.
@DecorateAll(log)
class User {
delete() {}
create() {}
update() {}
}
추가 종속성을 끌어내고 싶지 않다면, 여기 @Papoch 구현의 단순화된 버전이 있습니다.
function DecorateAll(decorator: MethodDecorator) {
return (target: any) => {
const descriptors = Object.getOwnPropertyDescriptors(target.prototype);
for (const [propName, descriptor] of Object.entries(descriptors)) {
const isMethod =
typeof descriptor.value == "function" &&
propName != "constructor";
if (!isMethod) {
continue;
}
decorator(target, propName, descriptor);
Object.defineProperty(target.prototype, propName, descriptor);
}
};
}
function Throttle(
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
descriptor.value = function () {
console.log("throttle");
return original.call(this);
};
}
@DecorateAll(Throttle)
class SharedApiClient {
async fetch1() { }
async fetch2() { }
}
언급URL : https://stackoverflow.com/questions/47621364/js-ts-apply-decorator-to-all-methods-enumerate-class-methods
반응형
'programing' 카테고리의 다른 글
한 Excel 워크북에서 다른 워크북으로 모듈을 복사하는 VBA (0) | 2023.07.03 |
---|---|
SQL Server 2008에서 기존 테이블의 열 순서를 변경하는 방법 (0) | 2023.07.03 |
Python의 어레이가 느린 이유는 무엇입니까? (0) | 2023.07.03 |
VB는 정말로 대소문자를 구분하지 않습니까? (0) | 2023.07.03 |
PLSQL에서 단일 따옴표 이스케이프 (0) | 2023.07.03 |