2

I have created a decorator, in Project A (the main library) and would like to have all of those decorators automatically loaded when the app starts in Project B (the project using Project A). Is there anyway of doing this?

index.ts looks like this:

export function MyDecorator<T extends Controller>() {
  return (target: new () => T) => {
    // Do stuff with the decorator
  }
}

const server = http.createServer((req, res) => {

})
server.listen(8080)

Is there something that I can do to automatically execute @MyDecorator() on all classes in Project B without Project B having to do so?

MyClass1.ts

import { MyDecorator } from 'project-a'

@MyDecorator()
export class ProjectBClass1 {}

MyClass2.ts

import { MyDecorator } from 'project-a'

@MyDecorator()
export class ProjectBClass2 {}
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • I'm not sure you can do this, node had `global` but I'm not sure either it could help. Do you had any example in one of opensource library out there? I only know NestJS and it had the decorator exported. – mandaputtra Mar 15 '20 at 16:48
  • I have never used NestJS, but looking at the docs it might be what I want, but I am not sure. In the docs it doesn't look like they ever reference their controllers, they just create them and they are there, which is what I am kinda looking for. – Get Off My Lawn Mar 15 '20 at 16:52
  • No, you still need to Import its decorators in NestJS, I mean if you had any opensource example I would love to dig in. I only use TS in NestJS and Angular, and they always export it. I don't see any global implementation on this. – mandaputtra Mar 15 '20 at 19:36
  • @mandaputtra Importing the decorators is fine, I just don't want to have to import `MyClass1.ts` or `MyClass2.ts`, I would like them to be auto imported. – Get Off My Lawn Mar 16 '20 at 14:35
  • @GetOffMyLawn -- did you find a nice solution for this? – Jonathan Mar 20 '21 at 11:06
  • @Jonathan no, I never did find a solution to this. – Get Off My Lawn Mar 20 '21 at 21:50

1 Answers1

1
  • I assume you mean creating instances by load .
  • Also I'm not sure if that is an elegant solution but here is my suggestion:

Create a class that has a static method:

class ControllerCreator {
  private static constrollerInstances: any = []
  private static controllerConstructors : any = [];  

  static registerControllerClass(ctor: any) {
    ControllerCreator.controllerConstructors.push(ctor);
  }

  static createInstances() {
    ControllerCreator.controllerConstructors.forEach(
      ctor => constrollerInstances.push(new ctor()) // pushing them to static array to not lose
    )
  }
}

In your decorator you should register your controller constructor:

export function MyDecorator<T extends Controller>() {
  return (target: new () => T) => {
    // Do stuff with the decorator
    class newClass extends target {
      // ...
    }

    ControllerCreator.registerControllerClass(newClass);
  }
}

And finally at some point you should call:

ControllerCreator.createInstances();
yez
  • 36
  • 3
  • No, I do not want to create instances. I want to execute my decorators without having to do a `import {...} from '...'` within my code. I just want them to automatically import or automatically bootstrap the files. – Get Off My Lawn Mar 15 '20 at 16:40
  • Do you just want to get rid of import statements? If so is that helpful for you: https://stackoverflow.com/questions/47736473/how-to-define-global-function-in-typescript – yez Mar 15 '20 at 17:11
  • In **Project B** yes. In **Project A** I would like to not load the files, but I could just glob them and do an import there if need be, but would really like to not have to. – Get Off My Lawn Mar 15 '20 at 17:14