如何正确设置NGXS带参数选择器的返回类型
解决NGXS带参数选择器的类型标注问题
这个问题的核心在于带参数的NGXS选择器不能直接用@Selector装饰器,而且你之前的返回类型标注完全错误——createSelector返回的是一个选择器函数,不是直接的AccountDetails实例,所以才会出现类型不匹配的报错。
下面是正确的写法和类型标注方案:
核心修正点
- 移除带参数方法上的
@Selector装饰器:@Selector是用来定义无参数的、可直接复用的选择器,带参数的选择器本质是一个「选择器工厂函数」,它返回由createSelector创建的选择器实例。 - 正确标注返回类型:使用NGXS提供的
Selector泛型类型,指定选择器依赖的状态类型和最终返回的数据类型(注意find可能返回undefined,所以类型要包含这个情况)。
修正后的完整代码
import { createSelector, Selector } from '@ngxs/store'; import { AccountDetails } from '@models/accounts'; import { RootStateModel } from '@state/root-state'; import { AccountsDbState } from './accounts.state'; import { DatabaseStoreStateModel } from 'ngx-rbk-utils'; export class AccountsDbSelectors { @Selector([AccountsDbState]) public static all(state: DatabaseStoreStateModel<AccountDetails>): AccountDetails[] { return state.items; } // 带参数的选择器:工厂函数,返回正确类型的选择器 public static single(id: string): Selector<RootStateModel, AccountDetails | undefined> { return createSelector( [AccountsDbState], (state: RootStateModel) => state.database.accounts.items.find(x => x.id === id) ); } // 优化版:直接依赖AccountsDbState的状态模型,无需访问根状态 public static singleOptimized(id: string): Selector<DatabaseStoreStateModel<AccountDetails>, AccountDetails | undefined> { return createSelector( [AccountsDbState], (state: DatabaseStoreStateModel<AccountDetails>) => state.items.find(x => x.id === id) ); } }
为什么这样写?
- 对于
single方法:我们标注它返回Selector<RootStateModel, AccountDetails | undefined>,意思是这是一个基于RootStateModel的选择器,最终会返回AccountDetails实例或undefined(当找不到匹配ID的账户时)。 - 优化版的
singleOptimized更符合NGXS的设计:直接依赖AccountsDbState对应的状态模型DatabaseStoreStateModel<AccountDetails>,不需要从根状态逐层访问,代码更简洁且类型更精确。
使用方式
在组件或服务中调用这个参数化选择器时,需要传入ID并传递给store.select:
// 假设你注入了Store constructor(private store: Store) {} getAccount(id: string) { return this.store.select(AccountsDbSelectors.single(id)); }
内容的提问来源于stack exchange,提问作者rbasniak
相关产品推荐
相关产品推荐

