Arios
@Arios

Как в ts распределить поля объека в другой объект?

export default interface IComponent {
  name: string;
};

export interface IComponentsList {
  [key: string]: IComponent;
}

export interface IComponents {
  health: IHealth[];
}

class Entity implements IEntity {
  readonly id: string = '';
  components: IComponentsList = {};
}

class Main {
  components: IComponents = {
    health: [],
  };
  entities: Map<string, IEntity> = new Map();

  addEntity(entity: IEntity) {
    for ( let componentKey in entity.components ) {
      if (entity.components.hasOwnProperty(componentKey)) {
        this.components[componentKey].push(entity.components[componentKey]);
      }
    }
  }
}


Есть сущности, их может быть много и разных. Сущности - это объект-контейнер, который содержит поле с id и объект с компонентами.
Также, существует класс Main, который должен собрать все компоненты у всех сущностей.
Проблема заключется в том, что при попытке это осуществить появляется ошибка: "Element implicitly has an 'any' type because type 'IComponents' has no index signature." Из ошибки следует, что "IComponents" необходимо переделать на подобии "IComponentsList", но мне нужно оставить строгое описание этого интерфейса.
  • Вопрос задан
  • 375 просмотров
Пригласить эксперта
Ответы на вопрос 1
Robur
@Robur
Знаю больше чем это необходимо
IComponentsList у вас по описанию может содержать любое свойство.
и вы его пушите в IComponents, в котором хотите "строгое" описание. Это несовпадение типов и потенциальный баг от которого вас компилятор честно защищает -иначе у вас в рантайме в components в Main может быть совсем не то что написано в типах.
самым правильным будет добавить индексную сигнатуру в IComponents.

Но если вы уверены в себе и хотите заставить компилятор вам поверить, можно сделать следующее:
this.components[componentKey as keyof IComponents].push(entity.components[componentKey]);

или
(this.components as any)[componentKey].push(entity.components[componentKey]);

или еще каким то образом подавить компилятор в этом месте.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы