'Typescript errors in `store.select()` after upgrading from ngrx@12 to 13

After I upgraded ngrx from v12 to v13 I'm getting such errors when using store.select(selector)

TS2769: No overload matches this call.   Overload 1 of 9, '(mapFn: (state: AppState) => Project[]): Observable<Project[]>', gave the following error.     Argument of type 'MemoizedSelectorWithProps<Object, unknown, Project[], DefaultProjectorFn<Project[]>>' is not assignable to parameter of type '(state: AppState) => Project[]'.   Overload 2 of 9, '(key: keyof AppState): Observable<AuthState | CompanyContextState | CoreState | UIState | DepartmentState | TaskViewFiltersState | TaskViewFiltersStateMobile | { ...; } | ProjectViewFilters>', gave the following error.     Argument of type 'MemoizedSelectorWithProps<Object, unknown, Project[], DefaultProjectorFn<Project[]>>' is not assignable to parameter of type 'keyof AppState'.       Type 'MemoizedSelectorWithProps<Object, unknown, Project[], DefaultProjectorFn<Project[]>>' is not assignable to type '"projectViewFilters"'.

My specific case is:

this.store.select(selectProjectsByCompany) // <- here errors

Selector definition

export const selectProjectsByCompany = createSelector(
  selectCompanyContext,
  getUser,
  projectSelectors.selectEntities,
  (
    { companyId }: CompanyContextState,
    currentUser: User,
    projects: Project[],
  ): Project[] => {
    if (currentUser) {
      if (currentUser.role === UserRole.SUPERADMIN) {
        return projects.filter(
          (project: Project) => project.companyId === companyId,
        );
      } else {
        return projects.filter(
          (project: Project) => project.companyId === currentUser.companyId,
        );
      }
    }
    return [];
  },
);

2 slice selectors

export const selectCompanyContext = (state: AppState): CompanyContextState =>
  state.companyContext;
export const getUser = createSelector(
  authObj,
  (state: AuthState) => state.user,
);

And the typing for AuthState.

export class AuthState {
  permissions: string[];
  expires: number;
  user: any;
  username: string;
  isAuthenticated: boolean;
  token: string;
  refreshToken: string;
}


Solution 1:[1]

It came out that typings should be inferred from AuthState. A selector getUser supposed to return User type. Because typings is not explicitly declared in case of AuthState.user it couldn't be inferred.

State typings should be carefully and explicitly declared to not to rely on workarounds like: createSelector<AppState, [CompanyContextState, User, Project[]], Project[]>

Solution 2:[2]

the issue is with your feature (reducer) selector that on upgrade has to be changed from something like:

export const selectYourReducer = (state) => state[reducerKeys.yourKey];

to something like:

export const selectYourReducer = createFeatureSelector(reducerKeys.yourKey) as YourReducerState;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Memke
Solution 2