Я не совсем уверен, что вы хотите, но, возможно, вы можете посмотреть на что-то вроде этого:
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) || [];
}
}
Идея здесь заключается в том, что ComponentStore
и IComponentStore
уже получают универсальный тип T дляэкземпляры IComponent, которые он должен обрабатывать ...
Я предполагал, что IComponent
и EComponents
являются интерфейсами.Я предоставил фиктивную реализацию для них.Этот код должен правильно скомпилироваться.Он генерирует следующий JavaScript (нацеленный на 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) || [];
}
}
Надеюсь, это поможет вам.
Редактировать:
Кстати, IComponentStore
не должен быть универсальным для этого.Следующий код также работает:
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) || [];
}
}
Он генерирует тот же JavaScript.
Редактировать 2
Прошло пять дней с момента моего последнего редактирования.Но я обещал, что обновлю свой ответ еще раз, основываясь на новой информации, указанной в ваших комментариях.Извините за задержку.
Я предполагаю, что вы уже нашли подходящий ответ самостоятельно, но если нет, возможно, вы найдете некоторое вдохновение в следующем коде.Надеюсь, это поможет.
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));