In a similar scenario, we encounter the need for a generic class that can accept a factory function with parameters to instantiate the type. The solutions provided do not address this specific situation.
The TypeScript methodology suggests defining Factories using an interface that anticipates a parameterless constructor:
export interface QueryTypeFactory<T> {
new () : T;
}
TypeScript does not allow a factory function returning an instance of type T to be directly substituted as a type - despite constructors essentially being functions that yield T.
We discovered a workaround involving an unsafe cast within the factory method like so:
function dynamicFactory<T>(f: () => T): FactoryType<T> {
return f as any as FactoryType<T>;
}
This enables the creation of a factory function encapsulating a closure for dynamic object instantiation behavior:
function factory(argument : any) : DynamicType {
return new DynamicType(argument);
}
To utilize the dynamic factory, it can be implemented as follows:
let argument = { ... };
new ThingThatCreatesEntities(dynamicFactory(() => factory(argument)));
The key lies in casting the factory method to 'any' and then to the necessary factory type. Although inelegant, this approach is functional and can be concealed within your implementation.
One advantage of this strategy is the ability to substitute the dynamic factory for an actual type, such as:
new ThingThatCreatesEntities(StaticType);
In this case, StaticType represents a class with a parameterless constructor.