NgRx类型不兼容报错:ActionReducer类型匹配问题求助
NgRx 14与Angular 14集成时ActionReducer类型不兼容问题解决
错误信息
Type '(state: { userName: string; userMessage: string; }[] | undefined, action: AddMessageAction) => { userName: string; userMessage: string; }[]' is not assignable to type 'ActionReducer<{ userName: string; userMessage: string; }[], Action>'. Types of parameters 'action' and 'action' are incompatible. Property 'payload' is missing in type 'Action' but required in type 'AddMessageAction'.ts(2322)
问题原因
StoreModule.forRoot要求注册的Reducer必须兼容ActionReducer<T, Action>类型,即Reducer需要能处理所有Action类型(包括NgRx内部派发的系统Action)。当前Reducer仅接收自定义的AddMessageAction类型,导致类型不匹配。
解决方法
方法1:调整现有类式Action的Reducer类型
修改message.reducer.ts,将Action参数类型改为Action,并在case分支中做类型断言:
import { Action } from '@ngrx/store'; import { MESSAGE_ACTION_TYPES, AddMessageAction } from './message.action'; import { IMessage } from './message.model'; const INITIAL_STATE: IMessage[] = []; export const MessageReducer = ( state = INITIAL_STATE, action: Action // 修改为Action类型 ) => { switch (action.type) { case MESSAGE_ACTION_TYPES.ADD_MESSAGE: // 断言action为AddMessageAction以访问payload return [...state, (action as AddMessageAction).payload]; default: return state; } };
方法2:使用NgRx 14推荐的函数式API(更优)
NgRx 14官方推荐使用createAction和createReducer定义Action和Reducer,自动处理类型推导,避免手动类型维护:
1. 修改message.action.ts
import { createAction, props } from '@ngrx/store'; import { IMessage } from './message.model'; // 用createAction定义Action export const addMessage = createAction( '[MESSAGING] Add Item', props<{ payload: IMessage }>() ); export const addMessageSuccess = createAction( '[MESSAGING] Add Item Success' ); export const addMessageFailure = createAction( '[MESSAGING] Add Item Failure', props<{ error: string }>() );
2. 修改message.reducer.ts
import { createReducer, on } from '@ngrx/store'; import { addMessage } from './message.action'; import { IMessage } from './message.model'; const INITIAL_STATE: IMessage[] = []; // 用createReducer创建Reducer export const MessageReducer = createReducer( INITIAL_STATE, on(addMessage, (state, { payload }) => [...state, payload]) );
两种方法都能解决类型不兼容问题,方法2更符合NgRx现代用法,代码更简洁且不易出错。
内容的提问来源于stack exchange,提问作者Package.JSON
相关产品推荐
相关产品推荐

