brahn
brahn

Reputation: 12376

node/typescript: how to ensure imports with side effects are run?

I am writing a node app in typescript. I have written a class decorator @myDecorator, and the purpose of @myDecorator is such that I need to keep track of all the classes to which it's applied.

My question: how do I make sure all of those decorated classes are loaded before making use of that behavior? Some example code will help to make this more concrete:

  1. Declaration of the decorator in file myDecorator.ts:
type ConstructorType = { new (...args: any[]): any };

// keep track of decorated classes
const registeredClasses: Map<string, ConstructorType> = new Map();

// class decorator
export function myDecorator<T extends ConstructorType>(targetConstructor: T) {
  // create the modified class
  const newClass = class extends targetConstructor { /* ... */ }
  // register the modified class
  registeredClasses.set(targetConstructor.name, newClass);
  // and return it
  return newClass;
}

export function doSomethingWithMyDecoratedClasses() {
  //... some behavior that relies on `registeredClasses`
}
  1. Declaration of a decorated class in file someClass.ts
import {myDecorator} from 'myDecorator.ts'

@myDecorator
class SomeClass { /* ... */ }
  1. Making use of doSomethingWithMyDecoratedClasses in anotherFile.ts:
import { doSomethingWithMyDecoratedClasses } from 'myDecorator.ts`
//...
doSomethingWithMyDecoratedClasses()
//...

The problem is that I need to make sure that SomeClass has been added to registeredClasses before I make this call to doSomethingWithMyDecoratedClasses. And, in fact, I've written a number of such classes in my app, and I need to make sure they are all registered.

My current best understanding is that I need to call import 'someClass.ts' in anotherFile.ts (and, in fact, import all files where decorated classes are declared), so really I need to import someClass1.ts, import someClass2.ts, ...

Is that the best/only approach? Is there a recommended pattern for doing so?

Upvotes: 4

Views: 753

Answers (1)

frodo2975
frodo2975

Reputation: 11725

Most applications have an index file that is responsible for importing the top level things. If you import doSomethingWithMyDecoratedClasses there, you'll guarantee that everything else is imported first.

An alternative would be to not call it in the root level of a module, and instead wait for an event.

Upvotes: 1

Related Questions