I'm trying to write a simple method decorator, that does some simple logic before calling the original method. All the examples I could find boil down to calling originalMethod.apply(this, args)
at the end -- but with noImplicitThis
enabled in tsconfig.json
, I get the following error:
[eval].ts(1,224): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
I tried working around by calling originalMethod.apply(this as any, args)
, but the error persists.
Question: Are there any workarounds to call the original method, without disabling noImplicitThis
for the whole project?
Minimal example -- works with noImplicitAny
disabled:
function logBeforeCall1(): originalMethodDecorator {
return function(
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): PropertyDescriptor {
const originalMethod = descriptor.value;
descriptor.value = (...args: any[]) => {
console.log('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
class Test1 {
private num: number = 1;
@logBeforeCall1()
test(next: number): void {
console.log(this.num, '->', next);
this.num = next;
}
}
this
in the above example worksnoImplicitThis
compiler option...Thanks to @Grassator for inspiration -- this is a version that works. I don't believe this can be done type-safely in the current state of TypeScript though.
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.log('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
...
> t2.test(5)
hello!
1 '->' 5
I do not think you can really get type safety, but if you just want to get rid of type error you can explicitly say that this: any
(3rd line):
function logBeforeCall1() {
return function (
this: any,
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): PropertyDescriptor {
const originalMethod = descriptor.value;
descriptor.value = (...args: any[]) => {
console.log('hello!');
return originalMethod.apply(this, args);
};
return descriptor;
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With