Я пытаюсь написать простой декоратор метода, который выполняет простую логику перед вызовом исходного метода. Все примеры, которые я смог найти, сводятся к вызову originalMethod.apply(this, args)
в конце, но с включенным noImplicitThis
в tsconfig.json
я получаю следующую ошибку:
[eval].ts(1,224): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
Я попытался обойтись, позвонив в originalMethod.apply(this as any, args)
, но ошибка не исчезла.
Вопрос: Существуют ли какие-либо обходные пути для вызова исходного метода, без с отключением noImplicitThis
для всего проекта?
Минимальный пример - работает с отключенным noImplicitAny
:
function logBeforeCall1(): originalMethodDecorator {
return function(
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): PropertyDescriptor {
const originalMethod = descriptor.value;
descriptor.value = (...args: any[]) => {
console.info('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
class Test1 {
private num: number = 1;
@logBeforeCall1()
test(next: number): void {
console.info(this.num, '->', next);
this.num = next;
}
}
this
в приведенном выше примере работает.noImplicitThis
...Я не думаю, что вы действительно можете получить безопасность типов, но если вы просто хотите избавиться от ошибки типа, вы можете явно указать, что this: any
(3-я строка):
function logBeforeCall1() {
return function (
this: any,
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): PropertyDescriptor {
const originalMethod = descriptor.value;
descriptor.value = (...args: any[]) => {
console.info('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
Но, вдохновленный вашим ответом, я нашел решение - аргумент this
нужно добавить к фактическому замещаемому методу, а не к функции декоратора.
Спасибо @Grassator за вдохновение - эта версия работает. Однако я не верю, что это можно сделать с безопасным типом в текущем состоянии TypeScript.
function logBeforeCall2(): originalMethodDecorator {
return function(
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): PropertyDescriptor {
const originalMethod = descriptor.value;
descriptor.value = function(this: any, ...args: any[]): any {
console.info('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
...
> t2.test(5)
hello!
1 '->' 5
Это компилируется, но не выполняется во время выполнения: `test (next) {console.info (this.num, '->', next); this.num = следующий; } `->
TypeError: Cannot read property 'num' of undefined at test ([eval].ts:5:35)