Reputation: 150
Based on this answer, I tried to implement a function from another service inside a decorator.
Here is my attempt:
export function ClearCache() {
const injectCacheService = Inject(CacheService);
return (target: any, _: string, propertyDescriptor: PropertyDescriptor) => {
injectCacheService(target, 'service'); // this is the same as using constructor(private readonly logger: LoggerService) in a class
//get original method
const originalMethod = propertyDescriptor.value;
//redefine descriptor value within own function block
propertyDescriptor.value = async function (...args: any[]) {
try {
console.log(this);
const service: CacheService = this.service;
service.clearCacheById(args[1]);
return await originalMethod.apply(this, args);
} catch (error) {
console.error(error);
}
};
};
}
But I got Property 'service' does not exist on type 'PropertyDescriptor'.ts(2339)
Any idea on what part I am missing?
Update:
tsconfig.json has "strict":true. If it is enabled, then "this" would be strictly use the PropertyDescriptor interface.
Fixed the issue by changing "strict": false in the tsconfig.json.
How to reproduce?
Upvotes: 2
Views: 9638
Reputation: 3127
You can fix it easier with the follow: const service: CacheService = (this as any).service;
Greetings, Florian
Upvotes: 0
Reputation: 1283
Its unclear if you are using the NestJS cache-manager wrapper, if so you need to use the provider token when injecting and the type would be Cache.
export function ClearCache() {
const injector = Inject(CACHE_MANAGER)
return (target: any, _key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>) => {
injector(target, 'cacheManager')
const originalMethod = descriptor.value
descriptor.value = async function (...args: any[]) {
try {
const service: Cache = this.cacheManager
service.delete(args[1])
return await originalMethod.apply(this, args)
} catch (err) {
console.error(err)
return originalMethod(args)
}
}
}
}
If it is a different service, ensure that you are using the correct provider token, it is in the current modules scope and instantiated. If it isn't in current module, check it is global
Uploaded minimal repo of above code here.
Update:
tsconfig.json has "strict":true
. If it is enabled, then "this" would be strictly use the PropertyDescriptor interface.
Fixed the issue by changing "strict": false
in the tsconfig.json.
Upvotes: 5