redux ts(typescrip) reducer中action的类型检查

简介: 实现的业务场景,我想实现一个用户管理的功能,可以新增用户,删除,修改用户等。每一个功能都是独立的并且所需要的参数是不一样的,所以做了以下类型检查。

本人在写reducer中的action类的时候发现一些问题。为啥我的类型检查没有,过不了。后面实现了改功能,特在此记一笔。好记性不如烂笔头。


效果


20210430084829405.gif


我们就是要实现一个类似上图的效果,在每一个type中,action的类型是不一样。实现方式看下面的成功案例


成功案例


实现的业务场景,我想实现一个用户管理的功能,可以新增用户,删除,修改用户等。

每一个功能都是独立的并且所需要的参数是不一样的,所以做了以下类型检查。


公共类型


// common.ts // 公共类型
// 枚举每一个type类型。我是使用的枚举类型
export enum EUserListActionTypes {
  'add' = 'add',
  'del' = 'del',
  'upa' = 'upa',
  'setMore' = 'setMore'
}
/**
 * 每一个用户的对象类型
 */
export interface IUserObj {
  id: string,
  name: string,
  age?: number
}
/**
 * 修改用户的类型,id必选,其他的参数可选
 */
export type updateUser = { id: string } & Partial<IUserObj>
/**
 * 整个state的类型,里面包含一个用户列表
 */
export type userList = {
  userList: IUserObj[]
}
/**
 * 公共的action类型,一个泛型,必须包含两个属性,一个type,一个payload
 */
interface Action<T extends string, P> {
  type: T,
  payload: P
}
// 新增用户的action传值函数的返回值
export type addAction = Action<EUserListActionTypes.add, IUserObj>
// 修改用户的action传值函数的返回值
export type upaAction =  Action<EUserListActionTypes.upa, updateUser>
// 删除用户的action传值函数的返回值
export type delAction =  Action<EUserListActionTypes.del, Extract<{ id: string },updateUser> >
// 设置用户列表的action传值函数的返回值
export type setMoreAction = Action<EUserListActionTypes.setMore, IUserObj[]>
// 对于reducer的action的联合类型
export type ActionType = addAction | upaAction | delAction | setMoreAction


action


类型写好了了后,写action创造函数。如下:


import { addAction, delAction, EUserListActionTypes, IUserObj, setMoreAction, upaAction, updateUser, userList } from "../types/common";
/**
 * create an add userList action
 * @param payload 
 * @returns 
 */
export const createAddUserList = (payload: IUserObj): addAction => ({
  type: EUserListActionTypes.add,
  payload
})
/**
 * create a update userList action
 * @param payload 
 * @returns 
 */
export const createUpdateUserList = (payload: updateUser): upaAction => ({
  type: EUserListActionTypes.upa,
  payload
})
/**
 * create a delete userList action by id
 * @param payload 
 * @returns 
 */
export const createDelUserList = (payload: { id: string }): delAction => ({
  type: EUserListActionTypes.del,
  payload
})
/**
 * set more data in userList
 * @param payload 
 * @returns 
 */
export const createSetMoreUserList = (payload: IUserObj[]): setMoreAction => ({
  type: EUserListActionTypes.setMore,
  payload
})


最后写reducer


import { ActionType, EUserListActionTypes, userList } from "../types/common"
const initialState: userList = {
  userList: [
    { id: '1', name: 'cll', age: 12 },
    { id: '2', name: 'twinkle', age: 13 },
  ]
}
/**
 * userList reducer
 */
export default (state: userList = initialState, action: ActionType) => {
  switch (action.type) {
    case EUserListActionTypes.add:
      return ({ userList: [...state.userList, action.payload] })
    case EUserListActionTypes.upa:
      return state.userList.map(p => p.id === action.payload.id ? { ...p, ...action.payload } : p)
    case EUserListActionTypes.del:
      return state.userList.filter(f => f.id !== action.payload.id)
    case EUserListActionTypes.setMore:
      return ({ userList: [...state.userList, ...action.payload] })
    default:
      return state
  }
}
相关文章
vue2项目使用?.语法报错如何解决?(@babel/plugin-proposal-optional-chaining)
vue2项目使用?.语法报错如何解决?(@babel/plugin-proposal-optional-chaining)
376 0
Vue3接口数据报错TypeError: target must be an object
Vue3接口数据报错TypeError: target must be an object
1439 0
|
前端开发
ES6学习(十)—async 函数
ES6学习(十)—async 函数
|
JavaScript 前端开发 编译器
TS_React:Hook类型化
依赖类型推断 类型化 useState 类型化 useReducer 类型化 useRef 类型化 forwardRef 类型化 useEffect 和 useLayoutEffect 类型化 useMemo 和 useCallback 类型化 useContext 类型化自定义hook
|
前端开发
React+Hook+ts+antDesignMobile实现input自动获取功能
React+Hook+ts+antDesignMobile实现input自动获取功能
122 0
react+ts+hook封装一个table分页组件(建议收藏,直接使用)(2)
react+ts+hook封装一个table分页组件(建议收藏,直接使用)
203 0
|
API
react+ts+hook封装一个table分页组件(建议收藏,直接使用)
react+ts+hook封装一个table分页组件(建议收藏,直接使用)
194 0
|
API
react+ts+hook封装一个table分页组件(建议收藏,直接使用)(1)
react+ts+hook封装一个table分页组件(建议收藏,直接使用)
128 0
|
JavaScript 算法
js中函数内部属性arguments和this以及方法apply()和call()
js中函数内部属性arguments和this以及方法apply()和call()
|
前端开发
react学习案例14-store,action,reducer
react学习案例14-store,action,reducer
57 0
react学习案例14-store,action,reducer