如何在ngrx的effect中使用map操作符转换属性并解决类型报错
错误根因
你的问题由3个错误共同导致:
- 语法错误:给
FoosApiActions.foosLoaded传参时,对象内没有指定foos的键名,直接写foos.map(...)属于非法的对象属性语法,TS无法正确解析,才会抛出"不存在未知属性"的报错。 map方法使用错误:你当前的写法是直接修改原foo对象的start属性,且map会返回所有赋值表达式的结果(即Date对象的数组),而非你需要的FooModel数组。- 类型不匹配:原有
FooModel定义的start是string类型,转换为Date后和接口定义的类型冲突。
正确实现方案
按照ngrx的不可变数据最佳实践,推荐按以下步骤修改:
1. 调整类型定义,区分接口层和业务层模型
// 接口返回的原始数据结构 export interface RawFooModel { id: number; start: string; } // 业务逻辑中使用的结构 export interface FooModel { id: number; start: Date; }
2. 修改Service请求类型,用原始结构接收接口返回
export class FoosService { constructor(private http: HttpClient) {} all() { return this.http.get<RawFooModel[]>(BASE_URL); } }
3. 修正Effect中的转换逻辑
loadFoos$ = createEffect(() => this.actions$.pipe( ofType(FoosPageActions.enter), exhaustMap(() => this.foosService .all() .pipe( map(rawFoos => { const foos = rawFoos.map(raw => ({ ...raw, start: new Date(raw.start) })) return FoosApiActions.foosLoaded({ foos }); }) ) ) ) );
如果不想拆分两个模型,也可以直接把FooModel的start属性改为联合类型string | Date,但不推荐这种模糊类型的写法。
内容的提问来源于stack exchange,提问作者Shahar Shokrani
相关产品推荐
相关产品推荐

