Reputation: 29107
This is a pure Typescript/Generics question. The source of my question originates from the Angular/CDK (portal.d.ts):
/** Interface that can be used to generically type a class. */
export interface ComponentType<T> {
new (...args: any[]): T;
}
I'm trying to wrap my head around this one, without much luck so far. The problem can be seen from the test code I wrote to understand this:
export interface ComponentType<T> {
new (...args: any[]): T;
}
interface Bar<T> {
getData: () => T
}
class MyBooleanComponent implements Bar<boolean> {
getData(): boolean { return true; }
}
class MyGenericWrapper {
init<T>(comp: ComponentType<T>): T {
return new comp();
}
}
const wrapper = new MyGenericWrapper();
const instance = wrapper.init<boolean>(MyBooleanComponent);
(instance as Bar).getData();
As can be seen there are some problems with this code.
First, MyBooleanComponent
, which is not assignable to ComponentType<boolean>
. Its unclear to me how I can tell that MyBooleanComponent` returns booleans?
Second, if I cast (instance as Bar).getData();
the typescript compiler is unhappy with Bar
, it wants (instance as Bar<boolean>).getData();
but I would expect based on how I initialized/setup the whole thing it should be possible derive the boolean
right?
I'm not use if I'm doing something just wrong or maybe trying to do the impossible. Any help would be appreciated!
Upvotes: 1
Views: 56
Reputation: 893
I think the confusion is that type T
in MyGenericWrapper
is different to type T
in interface Bar
. You have set interface Bar
's generic type to boolean by MyBooleanComponenet
:
class MyBooleanComponent implements Bar<boolean> {
getData(): boolean { return true; }
}
Where as MyGenericWrapper
's generic type is set to MyBooleanComponent
const wrapper = new MyGenericWrapper();
const instance = wrapper.init<MyBooleanComponent>(MyBooleanComponent);
instance.getData();
Upvotes: 1