mardi 22 décembre 2020

How to make an Object Factory maintaining the type

I have created the following object factory to instantiate implementations of all my interfaces:


interface SomeInterface {
    get(): string;
}

class Implementation implements SomeInterface {
   constructor() {}
   get() { return “Hey :D”; }
}

type Injectable = {
  [key: string]: () => unknown;
};

// deno-lint-ignore prefer-const
let DEFAULT_IMPLEMENTATIONS: Injectable = {
    SomeInterface: new Implementation()
};

let MOCK_IMPLEMENTATIONS: Injectable = {};

class Factory {
  static getInstance(interfaceName: string, parameters: unknown = []) {
    if (MOCK_IMPLEMENTATIONS[interfaceName])
      return MOCK_IMPLEMENTATIONS[interfaceName]();
    return DEFAULT_IMPLEMENTATIONS[interfaceName]();
  }

  static mockWithInstance(interfaceName: string, mock: unknown) {
    MOCK_IMPLEMENTATIONS[interfaceName] = () => mock;
  }
}

export const ObjectFactory = {
  getInstance<T>(name: string): T {
    return Factory.getInstance(name) as T;
  },

  mockWithInstance: Factory.mockWithInstance,
};

const impl = getInstance<SomeInterface>(“SomeInterface”);

As you can see, this Factory lets you instantiation and mocking of those interfaces. The main problem is that I have to call this function with the name of the interface AND the interface to keep the type in the assignments:

getInstance<SomeInterfaceName>(“SomeInterfaceName”)

I have seen this question, but I do not like the idea of using a Base interface. Moreover, that approach does not keep the type neither.

Ideally, I would want to use my approach but without having to use the interface, that is, use only the name of the interface.

Aucun commentaire:

Enregistrer un commentaire