首页 > 解决方案 > 结合 MemoizedSelector 和普通选择器组成 ngrx 选择器

问题描述

我有一个正在慢慢迁移到新ngrx语法的大型项目。我们有许多选择器,它们是这样的普通函数:

export function appDetailsSelector(state$: Observable<AppState>): Observable<AppDetails> {
    return state$.pipe(map((appState: AppState) => appState.appDetails));
}

新的选择器使用以下代码编写createSelector

export const selectUserConfig: MemoizedSelector<AppState, UserConfig> = createSelector(
  selectUserData,
  (userData: UserData) => userData.config,
);

这两个都使用相同的状态形状,但是我如何结合起来创建一个新的选择器,将这两者与createSelector

我知道我可以在组件代码中使用管道来执行此操作:

combineLatest([
  this.store.pipe(appDetailsSelector),
  this.store.select(selectUserConfig),
], (appDetails, userConfig) => ...projector fn code...);

但这不可重用,我需要完成它createSelector以避免在多个组件中重复此操作。如果appDetailsSelector是用它创建的,createSelector它看起来像这样:

export const getUserBookmarks = createSelector(
  appDetailsSelector,
  selectUserConfig,
  (appDetails: AppDetails, userConfig: UserConfig) => appDetails.useBookmarks ? userConfig.bookmarks : []
);

但是这个Argument of type 'MemoizedSelector<AppState, UserConfig, DefaultProjectorFn<UserConfig>>' is not assignable to parameter of type 'SelectorWithProps<Observable<AppState>, unknown, UserConfig>'.   Types of parameters 'state' and 'state' are incompatible.     Type 'Observable<AppState>' is missing the following properties from type 'AppState'...

我可以看到旧式选择器采用Observable<AppState>而新式选择器采用AppState;如何弥合这个差距并结合这两个选择器?

标签: angulartypescriptngrxngrx-selectors

解决方案


您可以使用类型转换

export const getUserBookmarks = createSelector(
  appDetailsSelector as MemoizedSelector<AppState, UserConfig, DefaultProjectorFn<UserConfig>>,
  selectUserConfig as MemoizedSelector<AppState, UserConfig, DefaultProjectorFn<UserConfig>>,
  (appDetails: AppDetails, userConfig: UserConfig) => appDetails.useBookmarks ? userConfig.bookmarks : []
);

类型转换会将类型设置为相同的类型


推荐阅读