React-redux with Flow - 来自导入常量的动作类型名称

问题描述 投票:0回答:1

我正在使用Flow在React应用程序中使用Red来进行类型检查,并且需要根据操作类型检查reducers中的操作形状,如下所述:https://flow.org/en/docs/react/redux/

减速机代码:

import { ADD_USER, DELETE_USER } from './actionTypes'

type State = {
  users: { [userId: number]: { name: string, age: number } }
};  // exact State shape is not important for this case

type Action = 
  |{ type: ADD_USER, user: {name: string, age: number} }
  |{ type: DELETE_USER, userId: number };

function reducer(state: State, action: Action): State {
  switch(action.type) {
    case ADD_USER:
      return { ...state, users: { ...state.users, action.user } };

    case DELETE_USER:
      const { action.userId, ...newUsers } = state.users
      return { ...state, users: newUsers };

    default:
      return state;
  }

这不起作用,给出流量错误Cannot get 'action.userId' because property 'userId' is missing in object type

当我在同一个文件中将动作类型定义为常量时,类型检查有效:

// import { ADD_USER, DELETE_USER } from './actionTypes'

const ADD_USER = 'ADD_USER';
const DELETE_USER = 'DELETE_USER';

type State = {
  users: { [userId: number]: { name: string, age: number } }
};  // exact State shape is not important for this case

type Action = 
  |{ type: ADD_USER, user: {name: string, age: number} }
  |{ type: DELETE_USER, userId: number };

function reducer(state: State, action: Action): State {
  switch(action.type) {
    case ADD_USER:
      return { ...state, users: { ...state.users, action.user } };

    case DELETE_USER:
      const { action.userId, ...newUsers } = state.users
      return { ...state, users: newUsers };

    default:
      return state;
  }

需要将操作类型名称导入为字符串常量,因为它们也是在动作创建器中导入的,因此可以将它们全部定义在一个文件actionTypes.js中(使用react-redux的一种标准方法)。

如何使用导入的常量执行使用Disjoint Unions进行流类型检查?

javascript react-redux flowtype
1个回答
1
投票

我认为有一些事情需要做。

1)在actionTypes.js中为类型添加类型。确保在那里分配了动作类型,如下所示:

const ADD_USER: 'ADD_USER' = 'ADD_USER';
const DELETE_USER: 'DELETE_USER' = 'DELETE_USER';

2)在reducer代码的Action类型注释中,确保使用类型而不是动作类型的值,如下所示:

import { ADD_USER, DELETE_USER } from './actionTypes'

type Action = 
  |{ type: typeof ADD_USER, user: {name: string, age: number} }
  |{ type: typeof DELETE_USER, userId: number };

3)确保所有其他代码都是有效的JavaScript,因为users: { ...state.users, action.user }{ action.userId, ...newUsers } = state.users看起来不像是解析和创建新对象的合法方式。

© www.soinside.com 2019 - 2024. All rights reserved.