I want to create a function that accepts classes (not instances) and the returns class instance types. This is what I want to achieve:
class A { a: number };
class B { a: string };
const view = createView(A, B);
// typeof view == [A, B]
So far, I created a generic that recursively convert the class instance type to a class:
class Component1 {
public declare a : number;
}
class Component2 {
public declare b : number;
}
type ComponentClass<TComponent, TArgs extends unknown[]> = {
new (...args: TArgs): TComponent;
};
type WrapInClasses<T extends unknown[]> = T extends [infer R, ...infer U] ? [ComponentClass<R, unknown[]>, ...WrapInClasses<U>] : []
type Res = WrapInClasses<[Component1, Component2]>
// Res = [ComponentClass<Component1, unknown[]>, ComponentClass<Component2, unknown[]>]
This part works; however, when I try to use in a function, I keep getting error about type mismatch:
const createView = <T extends unknown[]>(...args: WrapInClasses<T>): T => {
// Do not care about the internals for now
return null as any;
}
const view = createView(Component1, Component2);
// Error: Expected 0 arguments, got 2
When I hover over the function call, the type that I am getting is the following:
const createView: <unknown[]>() => unknown[]
If I provide a type in the generic, everything works as expected:
const view2 = createView<[Component1, Component2]>(Component1, Component2);
// typeof view2 = [Component1, Component2]
Is there a way that I can make the function infer the types instead of forcefully passing the types?