I'm not entirely certain about your requirements, but you might find the following code snippet helpful:
interface EComponents {
//...
}
interface IComponent {
//...
}
interface IComponentStore<T extends IComponent> {
setComponent(componentName: EComponents, component: T): void;
getComponents(componentName: EComponents): T[];
}
class ComponentStore<T extends IComponent> implements IComponentStore<T> {
private components = new Map<EComponents, T[]>();
setComponent(componentName: EComponents, component: T): void {
const components = this.components.get(componentName) || [];
this.components.set(componentName, [...components, component ]);
}
getComponents(componentName: EComponents): T[] {
return this.components.get(componentName) || [];
}
}
The concept here is that ComponentStore
and IComponentStore
are already configured to handle instances of generic type T for IComponent...
I assumed that IComponent
and EComponents
are interfaces. Placeholder implementations have been provided for them. This code should compile without any issues. It compiles to the following JavaScript (targeting ESNext):
"use strict";
class ComponentStore {
constructor() {
this.components = new Map();
}
setComponent(componentName, component) {
const components = this.components.get(componentName) || [];
this.components.set(componentName, [...components, component]);
}
getComponents(componentName) {
return this.components.get(componentName) || [];
}
}
I hope this proves useful to you.
Edit:
Additional note, IComponentStore
does not necessarily need to be generic for this scenario. The following code variation also functions correctly:
interface EComponents {
//...
}
interface IComponent {
//...
}
interface IComponentStore {
setComponent(componentName: EComponents, component: IComponent): void;
getComponents(componentName: EComponents): IComponent[];
}
class ComponentStore<T extends IComponent> implements IComponentStore {
private components = new Map<EComponents, T[]>();
setComponent(componentName: EComponents, component: T): void {
const components = this.components.get(componentName) || [];
this.components.set(componentName, [...components, component ]);
}
getComponents(componentName: EComponents): T[] {
return this.components.get(componentName) || [];
}
}
This version translates to the same JavaScript output.
Edit 2
It has been five days since my last update, so I wanted to make good on my promise to incorporate any new information from your feedback. My apologies for the delay.
In case you haven't found a suitable solution yet, I have included another code example below that could serve as inspiration. I hope it offers some assistance.
enum EComponents {
health = 'health',
wealth = 'wealth'
}
interface IComponent {
name: EComponents;
value: string;
}
interface IComponentStore {
setComponent<T extends IComponent>(component: T): void;
getComponents<T extends IComponent>(componentName: EComponents): T[];
}
class ComponentStore implements IComponentStore {
private components: Map<EComponents, IComponent[]> = new Map();
setComponent<T extends IComponent>(component: T): void {
const components: IComponent[] = this.components.get(component.name) || [];
this.components.set(component.name, [...components, component]);
}
getComponents<T extends IComponent>(componentName: EComponents): T[] {
return (this.components.get(componentName) || []) as T[];
}
}
class Health implements IComponent {
name: EComponents = EComponents.health;
constructor(public value: string) {
}
}
class Wealth implements IComponent {
name: EComponents = EComponents.wealth;
constructor(public value: string) {
}
}
const store = new ComponentStore();
store.setComponent(new Health('ill'));
store.setComponent(new Health('fairly healthy'));
store.setComponent(new Health('top condition'));
store.setComponent(new Wealth('poor'));
store.setComponent(new Wealth('prosperous'));
store.setComponent(new Wealth('filthy rich'));
console.log(store.getComponents(EComponents.health));
console.log(store.getComponents(EComponents.wealth));