TS говорит, что свойство объекта не существует, показывая, что оно существует

#angular #typescript #rxjs-marbles

#angular #typescript #rxjs-шарики

Вопрос:

У меня возникла проблема, когда я получаю сообщение об ошибке в возвращаемом значении заглушенной функции, которое имитирует возврат наблюдаемого (с использованием rxjs-marbles ).

Проблема, с которой я сталкиваюсь, заключается в том, что в сообщении об ошибке, похоже, указано, что свойство объекта не существует для возвращаемого типа.

Из файла модульного теста

 it('', marbles((m) => {
     stub(ambulatoryListDataManager, 'combinedMultipleSearchStatuses').returns(
        m.cold('a', [
          {
            searchStatus: SearchStatus.active, // SearchStatus is an enum type
            flags: { loaded: true, loading: false },
            list: recordList,
          },
          {...},
        ]),
      );
});
 

Я получаю ошибку следующего типа:

 Type '{ searchStatus: SearchStatus.active; flags: { loaded: true; loading: false; }; list: IRecord[]; }' is not assignable to type '{ searchStatus: SearchStatus; flags: ListFlagsSelection; list: IRecord[]; }[]'.
  Object literal may only specify known properties, and 'searchStatus' does not exist in type '{ searchStatus: SearchStatus; flags: ListFlagsSelection; list: IRecord[]; }[]'

context.d.ts(11, 9): The expected type comes from this index signature
 

Как вы можете видеть, само свойство searchStatus , которое, по его утверждению, не существует в Object literal , находится прямо в определении типа, показанном в сообщении об ошибке. Похоже, он не жалуется на другие свойства.

Пожалуйста, обратите внимание, что SearchStatus это тип перечисления.

Мне все кажется совершенно нормальным, так почему я получаю эту ошибку?

Это предполагаемая типизация, поэтому я подумал, что, возможно, это помогло бы сделать возврат функции явным, но это не помогает, у меня все та же проблема.

Для дальнейшего контекста, если необходимо, вот функция, на которую опирается сама функция. Первая функция — это та, которая предоставляет сведения, которые typescript использует для вывода ожидаемого возврата.

 public combinedSearchStatuses(searchStatus: SearchStatus) {
    return combineLatest(...).pipe(
      map(([flags, list]) => ({ searchStatus, flags, list })),
    );
  }

  public combinedMultipleSearchStatuses(searchStatuses: SearchStatus[]) {
      return combineLatest(searchStatuses.map(
        (searchStatus) => this.combinedSearchStatuses(searchStatus)),
      ).pipe(distinctUntilChanged((a, b) => {...})

 

Ответ №1:

Ошибка немного вводит в заблуждение и ее трудно обнаружить, она жалуется, что searchStatus не существует для типа массива, который является true.

Эта строка специально,

 Type '{ searchStatus: SearchStatus.active; flags: { loaded: true; loading: false; }; list: IRecord[]; }' is not assignable to type '{ searchStatus: SearchStatus; flags: ListFlagsSelection; list: IRecord[]; }[]'.
 

Вот игровая площадка TS, чтобы дополнительно показать, почему

Я считаю, что вам нужно вернуть массив наблюдаемых, а не один наблюдаемый с массивом объектов.

Что-то вроде [m.cold('a', { ... }, m.cold('a', {...})]

Комментарии:

1. Возможно, мне следовало указать, что SearchStatus это перечисление, поэтому оно должно работать так. Использование only SearchStatus выдало бы ту же ошибку.

2. Я обновил свой ответ, похоже, мы оба были сбиты с толку ошибкой типа.

3. Спасибо за вашу помощь, Антонио, я только сейчас понял, что я упускаю из виду важный шаг в моем определении для определения наблюдаемого мраморного теста. Итак, вы отчасти правы, но то, что требуется, немного отличается, я добавлю ответ для объяснения.

Ответ №2:

После ответа Антониоса о необходимости возврата массива наблюдаемых я понял, что пропустил шаг в определении мрамора rxjs. Мне нужно определить шаг возврата для a

Вот как это должно выглядеть:

  stub(ambulatoryListDataManager, 'combinedMultipleSearchStatuses').returns(
        m.cold('-a', {
          a: [
            {
              searchStatus: SearchStatus.active,
              flags: { loaded: true, loading: false },
              list: recordList,
            },
            {
              searchStatus: SearchStatus.active,
              flags: { loaded: true, loading: false },
              list: recordList,
            },
          ],
 

Поскольку я забыл правильно определить объект, он жаловался, что возврат был определен неправильно