If you are considering utilizing the Reflect API, there is a specific approach you must follow. Initially, it is essential to store the module information for the target class as metadata in a class decorator before accessing it in your method decorator.
UPDATE:
My initial solution turned out to be more complex than anticipated; I overlooked the fact that method decorators are evaluated prior to class decorators, requiring a workaround.
decorators.ts
import "reflect-metadata";
export function InjectModuleInfo (filename: string) {
return function <T extends { new (...args: any[]): {} }> (constructor: T) {
Reflect.defineMetadata("modulePath", filename, constructor);
}
}
export function MyMethodDecorator (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(Reflect.getMetadata("modulePath", target.constructor));
}
TestClass.ts
import {MyClassDecorator, MyMethodDecorator} from './decorators';
@InjectModuleInfo(__filename)
class BaseClass {}
export class TestClass extends BaseClass {
@MyMethodDecorator
public myMethod () {}
}
For each class where this functionality is required, inheritance from a base class with the attached module info as metadata is necessary. Without this, if you directly apply the decorator to TestClass
, the class decorator may not be processed in time for the method decorator.