Home > Mobile >  TS saying that object property dosn't exists while showing it does
TS saying that object property dosn't exists while showing it does

Time:12-10

I'm having a problem where I'm getting an error message on the return value of a stubbed function, that mocks the return of an Observable (using rxjs-marbles).

The issue I'm having is that the error message seems to state that a property of an object does not exist on the return type.

From the unit test file

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,
          },
          {...},
        ]),
      );
});

I'm getting the following type error:

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

As you can see, the very property searchStatus, that it claims does not exist on the Object literal, is right there in the type definition shown in the error message. It does not seem to complain about the other properties.

Please note that SearchStatus is an enum type.

Everything seem completely fine to me, so why am I getting this error?

This is an inferred typing, so I though maybe it would help to make the return of the function explicit, but it does not help, I still have the same issue.

For further context, if needed, here is the function, and the function itself relies on. The first function is the one that provides the details that typescript uses to infer the expected return.

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) => {...})

CodePudding user response:

The error is slightly misleading and hard to spot, it is complaining that searchStatus doesn't exist on the array type which is true.

This line specifically,

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

Here is a TS playground to further show why

I believe you need to return an array of observables rather than one observable with an array of objects.

Something like [m.cold('a', { ... }, m.cold('a', {...})]

CodePudding user response:

After Antonios answer about the need to return array of Observables, I realized that I had overlooked a step in the definition of the rxjs marble. I need to define the return step for a

Here is how it should look like:

 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,
            },
          ],

Since I forgot to define the object correctly, it was complaining that the return was not correctly defined

  • Related