I am in need of an invoker function that will call factories for generating class instances based on a specified base class. The base class includes a generic parameter which is used as the type for the constructors first and only argument.
class ServiceBase<TArg = unknown> {
constructor(protected arg: TArg) {}
}
class NumberService extends ServiceBase<number> {}
The factory function should be defined as an inline function without explicit typings. It should accept one argument, with its type inferred from the base class' generic argument in the constructed class.
For example:
invokeFactory((arg) => new NumberService(arg))
In the given example, since the factory returns a NumberService
which extends ServiceBase<number>
, the argument should be inferred as type number
.
I have attempted to infer the Service type and Arg type successfully. However, when I specify the arg type in the function instead of using any, the Service type inference is not accurate:
Test code:
const invokeFactory = <
TService extends ServiceBase,
TArg = TService extends ServiceBase<infer T> ? T : never
>(
factory: (arg: any /* Dont use TArg*/) => TService
): [TService, TArg] => {
const magicArg: TArg = null!; // for simplification
return [factory(magicArg), magicArg];
};
const [numberService, arg] = invokeFactory((x) => new NumberService(x));
numberService
is inferred correctly as NumberService
and arg
as number
.
If there is a way to achieve this?