使用NgRx Effects时遇类型错误:MonoTypeOperatorFunction不兼容OperatorFunction
解决NgRx Effect中startWith的类型不匹配问题
我刚好遇到过类似的类型问题,这就帮你理清解决思路。
问题根源
你的actions$是Observable<Action>类型的流,而startWith(new LoadContainerAction())传入的是具体的LoadContainerAction实例。虽然这个类实现了Action接口,但TypeScript的类型推断在这里不会自动将子类实例向上兼容到父类型,导致操作符的类型MonoTypeOperatorFunction<LoadContainerAction>和流需要的OperatorFunction<Action, Action>不匹配。
解决方案
有两种简洁的方式可以修复这个类型错误:
1. 显式指定startWith的泛型类型
直接告诉TypeScript,startWith发射的值属于Action类型,让它和流的类型对齐:
@Injectable() export class Effects { @Effect() loadCollection$: Observable<Action> = this.actions$ .pipe( ofType(ActionTypes.LOAD_CONTAINER), // 显式指定泛型为Action,统一流的类型 startWith<Action>(new LoadContainerAction()), switchMap(() => this.apiService.loadContainers() .map(data => new LoadContainerSuccessAction(data)) .catch(error => of(new LoadContainerFailAction(error))) ) ); constructor(private actions$: Actions, private apiService: ApiService) {} }
2. 使用类型断言
如果你觉得泛型写法有点繁琐,也可以用类型断言把实例转为Action类型:
startWith(new LoadContainerAction() as Action)
补充说明
这两种方式本质都是让TypeScript明确知道startWith发射的值符合流的Action类型要求。个人更推荐第一种泛型写法,它比类型断言更清晰,也更符合TypeScript的类型安全设计理念。
内容的提问来源于stack exchange,提问作者Mikael Gidmark
相关产品推荐
相关产品推荐

