'Passing class constructor as parameter to a function expecting a function type

Say I have a function of type: (fooMaker: (_: string) => Foo): void where Foo is a class. Is it possible to pass the Foo constructor directly to such a function without having to wrap it like this first: (s: string) => new Foo(s)?



Solution 1:[1]

It is not possible.

Even if Foo's constructor takes just one string argument, it still doesn't mean that in itself, the constructor is assignable to type (_: string) => Foo.

Solution 2:[2]

I ended up writing a wrapper like this:

type ConsToFunc<C extends {new (...args: any[])}>=
    C extends { new (): infer O } ? () => O
    : C extends { new (a: infer A): infer O } ? (A) => O
    : C extends { new (a: infer A, b: infer B): infer O } ? (A, B) => O
    // ...etc
    : never

const consToFunc = <C extends {new (...args: any[]): any}>(c: C): ConsToFunc<C> => 
     (...args: []) => new c(...args)

The ConsToFunc type maps the constructor to a function type of the same shape and consToFunc is the actual wrapper that passes arguments from the outer function down to the constructor.

So in my example this would be used like this: consToFunc(Foo). It's not pretty but it's better than writing the wrapper manually, especially for constructors with several parameters.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Obumuneme Nwabude
Solution 2 pseudosudo