Reputation: 21
I'm trying to create a mapping GenericInterface -> ConcreteFactory<GenericInterface>
in typescript. And it works as long as GenericInterace
has no methods or properties. But if I'm adding something to this interface, than this error occurs: Property 'XXX' is missing in type 'typeof ClassThatImplementsGenericInterface' but required in type 'GenericInterface'
.
I assume that this happens because getOrCreate
expects instance and not a type, but i don't understand how I can implement such behaviour in typescript without using strings (component names) as dictionary keys.
// how factories are stored
private _factories: Dictionary<IComponent, Factory<IComponent>>;
// creates and returns factory for component
public getOrCreate<T extends IComponent>(component: IComponent): Factory<T> {
if (this._factories.has(component)) {
return this._factories.get(component) as Factory<T>;
}
let factory = new Factory<T>();
this._factories.set(component, factory);
return factory as Factory<T>;
}
// without XXX everything works
interface IComponent {
XXX(): string;
}
// this is where error occurs
factories.getOrCreate(TestComponent);
Upvotes: 0
Views: 84
Reputation: 3532
The Dictionary<IComponent
bit literally says, that your key is IComponent. However, this is not what you are trying to do: the key should rather be something that creates IComponent
.
Take a look at how the official documentation describes using constructors in interfaces.
Let's create another interface for that:
interface IComponentCtor {
new (): IComponent;
}
This describes something that creates IComponent (add constructor parameters as needed).
class TestComponent implements IComponent {
constructor() {} // complies with IComponentCtor
}
And the signature of getOrCreate is now
public getOrCreate(component: IComponentCtor): Factory<IComponent>
Now you can use TestComponent as a key of your dictionary as IComponentCtor: Dictionary<IComponentCtor, Factory<IComponent>>
.
Upvotes: 2