Поток (InferError): не удается получить «объект [ключ]», так как в «классе» отсутствует подпись индекса, объявляющая ожидаемый тип ключа / значения. - PullRequest
0 голосов
/ 02 июля 2019

Вот мой код для проверки равенства некоторых объектов класса.См. Мой другой вопрос , если вы хотите узнать, почему я не просто делаю expect(receivedDeals).toEqual(expectedDeals) и другие более простые утверждения.

   type DealCollection = { [key: number]: Deal };  // imported from another file

   it("does the whole saga thing", async () => {
      sagaStore.dispatch(startAction);
      await sagaStore.waitFor(successAction.type);
      const calledActionTypes: string[] = sagaStore
        .getCalledActions()
        .map(a => a.type);
      expect(calledActionTypes).toEqual([startAction.type, successAction.type]);
      const receivedDeals: DealCollection = sagaStore.getLatestCalledAction()
        .deals;
      Object.keys(receivedDeals).forEach((k: string) => {
        const id = Number(k);
        const deal = receivedDeals[id];
        const expected: Deal = expectedDeals[id];
        for (let key in expected) {
          if (typeof expected[key] === "function") continue;
          expect(expected[key]).toEqual(deal[key]);
        }
      });
    });

Тест проходит нормально, но я получаюОшибка потока при expected[key]:

Cannot get 'expected[key]' because an index signature declaring the expected key / value type is missing in 'Deal'

Я могу вставить код из Deal по запросу, но я думаю, все, что вам нужно знать, это то, что я не объявил подпись индекса (потому что я нене знаю как!).

Я немного искал, но не могу найти именно этот случай.

Обновление: я могу устранить ошибки, изменив deal и expected таким образом:

const deal: Object = { ...receivedDeals[id] };
const expected: Object = { ...expectedDeals[id] };

И так как я сравниваю свойства в цикле, это на самом деле не проблема,Но я бы подумал, что смогу сделать это с Deal s, и я хотел бы знать, как я объявляю подпись индекса, упомянутую в ошибке.

PS.Бонусный вопрос: В каком-то мире, где безумный ученый скрестил Дж.С. со Свифтом, я думаю, вы могли бы сделать что-то вроде

const deal: Object = { ...receivedDeals[id] where (typeof receivedDeals[id] !== "function" };
const expected = // same thing
expect(deal).toEqual(expected);

// And then after some recombining of objects:
expect(receivedDeals).toEqual(expectedDeals);

Это вообще что-то такое?

Редактировать:

Добавление небольшого определения класса Deal:

Deal.js (резюме)

export default class Deal {
  obj: { [key: mixed]: mixed };
  id: number;
  name: string;
  slug: string;
  permalink: string;
  headline: string;
  // ...other property definitions

  constructor(obj?: Object) {
    if (!obj) return;
    this.id = obj.id;
    this.name = obj.name;
    this.headline = obj.headline;
    // ...etc
  }

  static fromApi(obj: Object): Deal {
    const deal = new Deal();
    deal.id = obj.id;
    deal.name = obj.name;
    deal.slug = obj.slug;
    deal.permalink = obj.permalink;
    // ...etc
    return deal;
  }

  descriptionWithTextSize(size: number): string {
    return this.descriptionWithStyle(`font-size:${size}`);
  }

  descriptionWithStyle(style: string): string {
    return `<div style="${style}">${this.description}</div>`;
  }

  distanceFromLocation = (
    location: Location,
    unit: unitOfDistance = "mi"
  ): number => {
    return distanceBetween(this.location, location);
  };

  distanceFrom = (otherDeal: Deal, unit: unitOfDistance = "mi"): number => {
    return distanceBetween(this.location, otherDeal.location);
  };

  static toApi(deal: Deal): Object {
    return { ...deal };
  }

  static collectionFromArray(array: Object[]) {
    const deals: DealCollection = {};
    array.forEach(p => (deals[p.id] = Deal.fromApi(p)));
    return deals;
  }
}

1 Ответ

1 голос
/ 02 июля 2019

Подпись индекса (или свойство индексатора) определяется как [keyName: KeyType]: ValueType.Отличным примером является DealCollection: keyName - это key, KeyType - это number, а ValueType - это Deal.Это означает, что всякий раз, когда вы получаете доступ к свойству number объекта типа DealCollection, он возвращает Deal.Вы захотите добавить аналогичное выражение к определению Deal, чтобы получить доступ к произвольным свойствам в нем.Дополнительную информацию можно найти в разделе Объекты в виде карт в документации Flow.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...