Angular 15升级至16后Ngrx createEffect类型错误求助
升级Angular 16时NgRx类型校验导致的Effect编译错误解决
案例1:ResetOrderIdentifier Effect错误
原有代码
//Actions: export const RESET_ORDER_IDENTIFIER = '[ServiceProvisioning] Reset order identifier'; export const RESET_ORDER_IDENTIFIER_SUCCESS = '[ServiceProvisioning] Reset order identifier success'; export const resetOrderIdentifier = createAction(RESET_ORDER_IDENTIFIER); export const resetOrderIdentifierSuccess = createAction(RESET_ORDER_IDENTIFIER_SUCCESS, props<{ orderIdentifier: string}>()); //Effect: resetOrderIdentifier$ = createEffect(() => { return this.actions$.pipe( ofType(ServiceProvisioningActions.resetOrderIdentifier), map(() => { //generateGUID()返回随机字符串(非Observable) return ServiceProvisioningActions.resetOrderIdentifierSuccess({orderIdentifier: this._utilsService.generateGUID()}); }) ); });
错误信息
Argument type () => Observable<{orderIdentifier: string} & TypedAction<"[ServiceProvisioning] Reset order identifier success">> is not assignable to parameter type () => (Observable<{orderIdentifier: string} & TypedAction<"[ServiceProvisioning] Reset order identifier success">> & ConditionallyDisallowActionCreator<DispatchType<EffectConfig & {functional?: false}>, Observable<{orderIdentifier: string} & TypedAction<"[ServiceProvisioning] Reset order identifier success">>>)
解决方法
NgRx 16+对Effect的类型校验更严格,需显式指定Effect配置以匹配类型推断:
resetOrderIdentifier$ = createEffect( () => { return this.actions$.pipe( ofType(ServiceProvisioningActions.resetOrderIdentifier), map(() => { return ServiceProvisioningActions.resetOrderIdentifierSuccess({orderIdentifier: this._utilsService.generateGUID()}); }) ); }, { functional: false } );
案例2:SetSelectedServiceType Effect错误
原有代码
//Actions: export const SET_SELECTED_SERVICE_TYPE_ACTION = '[ServiceProvisioning] Set selected service type'; export const SET_SELECTED_SERVICE_TYPE_ACTION_SUCCESS = '[ServiceProvisioning] Set selected service type success'; export const setSelectedServiceType = createAction(SET_SELECTED_SERVICE_TYPE_ACTION, props<{ selectedServiceType: ServiceProvisioningState['selectedServiceType'] }>()); export const setSelectedServiceTypeSuccess = createAction(SET_SELECTED_SERVICE_TYPE_ACTION_SUCCESS, props<{ selectedServiceType }>()); //Effect: setSelectedServiceType$ = createEffect( () => { return this.actions$.pipe( ofType(ServiceProvisioningActions.setSelectedServiceType), switchMap( ({ selectedServiceType }) => { let pageTitle = selectedServiceType.includes('foo') ? 'foo bar' : 'bar'; this._store.dispatch(ServiceProvisioningActions.setPageTitle({pageTitle})); return of (ServiceProvisioningActions.setSelectedServiceTypeSuccess({selectedServiceType})); }) ); });
错误信息
Argument type () => Observable<{selectedServiceType} & TypedAction<"[ServiceProvisioning] Set selected service type success">> is not assignable to parameter type () => (Observable<{selectedServiceType} & TypedAction<"[ServiceProvisioning] Set selected service type success">> & ConditionallyDisallowActionCreator<DispatchType<EffectConfig & {functional?: false}>, Observable<{selectedServiceType} & TypedAction<"[ServiceProvisioning] Set selected service type success">>>)
解决方法
- 修正Action的类型定义,显式声明props类型:
export const setSelectedServiceTypeSuccess = createAction( SET_SELECTED_SERVICE_TYPE_ACTION_SUCCESS, props<{ selectedServiceType: ServiceProvisioningState['selectedServiceType'] }>() );
- 为Effect添加显式配置:
setSelectedServiceType$ = createEffect( () => { return this.actions$.pipe( ofType(ServiceProvisioningActions.setSelectedServiceType), switchMap( ({ selectedServiceType }) => { let pageTitle = selectedServiceType.includes('foo') ? 'foo bar' : 'bar'; this._store.dispatch(ServiceProvisioningActions.setPageTitle({pageTitle})); return of(ServiceProvisioningActions.setSelectedServiceTypeSuccess({selectedServiceType})); }) ); }, { functional: false } );
通用迁移要点
- NgRx 16+强化了Effect的类型校验,要求返回的Observable类型与ActionCreator输出类型完全匹配,隐式类型易引发错误。
- 类组件中的非函数式Effect,建议显式添加
{ functional: false }配置,帮助TypeScript正确推断类型。 - Action定义中,props必须显式声明属性类型,避免使用
props<{ propName }>这类隐式写法。
内容的提问来源于stack exchange,提问作者Jack Davies
相关产品推荐
相关产品推荐

