NgRx Store的reducer函数传入参数类型错误如何解决?
报错原因
NgRx 内置的 ActionReducer 泛型默认期望接收基础 Action 类型作为入参,你自定义的 TutorialActions.Actions 联合类型虽然在逻辑上兼容基础 Action,但默认的类型校验无法识别这种兼容关系,才会抛出参数类型不匹配的报错。不需要使用类型断言,有更合规的简单解决方式。
最简解决方案
直接给你的 reducer 函数添加 ActionReducer 类型标注即可,修改后的 reducer.ts 完整代码如下:
// 新增导入ActionReducer类型 import { Action, ActionReducer } from '@ngrx/store' import { Tutorial } from './../models/tutorial.model' import * as TutorialActions from './../actions/tutorial.actions' const initialState: Tutorial = { name: 'Initial Tutorial', url: 'http://google.com' } // 给reducer添加类型标注,泛型分别传入state类型、自定义Action联合类型 export const reducer: ActionReducer<Tutorial[], TutorialActions.Actions> = ( state: Tutorial[] = [initialState], action: TutorialActions.Actions ) => { switch(action.type) { case TutorialActions.ADD_TUTORIAL: return [...state, action.payload]; default: return state; } }
修改后不需要改动其他任何代码,即可消除类型报错,也完全符合NgRx的类型规范。
可选优化建议
如果你的NgRx版本 >=8,更推荐使用官方提供的 createReducer + createAction 写法,不需要手动定义Action类和联合类型,自动处理类型兼容,代码更简洁:
- 改造action文件:
import { createAction, props } from '@ngrx/store'; import { Tutorial } from '../models/tutorial.model'; export const addTutorial = createAction('[TUTORIAL] Add', props<{ payload: Tutorial }>()); export const removeTutorial = createAction('[TUTORIAL] Remove', props<{ payload: number }>());
- 改造reducer文件:
import { createReducer, on } from '@ngrx/store'; import { Tutorial } from './../models/tutorial.model'; import { addTutorial } from './../actions/tutorial.actions'; const initialState: Tutorial[] = [ { name: 'Initial Tutorial', url: 'http://google.com' } ]; export const reducer = createReducer( initialState, on(addTutorial, (state, { payload }) => [...state, payload]) );
内容的提问来源于stack exchange,提问作者Uri Gross
相关产品推荐
相关产品推荐

