You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NgRx createSelector获取Observable遇TS2740错误的解决方法

NgRx 15 createSelector 使用错误导致TS2740问题

问题背景

原本从NgRx Store获取数据的传统写法:

public getUser(): Observable<IUser> {
  return this.store.select(store => store.users.selectedUser);
}

尝试改用NgRx 15的createSelector方法后,代码写成这样:

public getUser(): Observable<IUser> {
    const user = createSelector((state: IAppState) => state.users,
        (userState) => {
            return userState;
        }
    );
    return user;
}

出现TS2740错误:

TS2740: Type 'MemoizedSelector<IAppState, IUserState, (s1: IUserState) => IUserState>' is missing the following properties from type 'Observable': source, operator, lift, subscribe, and 3 more.

需求是让getUser()返回Observable<IUser>,以支持如下订阅操作:

this.storeSelector.getUser().subscribe((a) => {
    console.log(a);
});

问题原因

createSelector的作用是创建一个记忆化的选择器函数,它本身返回的是MemoizedSelector类型,并不是Observable。直接返回这个选择器,不符合方法声明的Observable<IUser>返回类型,因此触发TypeScript类型错误。另外当前选择器返回的是整个userState,和原代码要获取的selectedUser类型不匹配,也会导致后续类型问题。

解决方法

需要将创建好的选择器传入store.select()方法,才能得到对应数据的Observable,同时修正选择器逻辑,确保返回正确的IUser类型数据。

推荐写法(复用选择器,保留记忆化优势)

// 在类外部或共享模块中定义可复用的选择器
const selectUserState = (state: IAppState) => state.users;
const selectSelectedUser = createSelector(
  selectUserState,
  (userState) => userState.selectedUser
);

// 类方法中调用选择器并转换为Observable
public getUser(): Observable<IUser> {
  return this.store.select(selectSelectedUser);
}

方法内部创建选择器(不推荐,每次调用都会生成新选择器,丢失记忆化效果)

public getUser(): Observable<IUser> {
  const selectSelectedUser = createSelector(
    (state: IAppState) => state.users,
    (userState) => userState.selectedUser
  );
  return this.store.select(selectSelectedUser);
}

修改后,store.select()会将选择器转换为对应数据的Observable,既能正常执行订阅操作,也能通过TypeScript的类型检查。

内容的提问来源于stack exchange,提问作者born2net

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:47:17