流类型检查:如何在redux操作中迭代可能未定义的属性?

时间:2017-08-27 07:02:15

标签: redux flowtype

我有一个Redux减少器用于首选项,我正在使用Flow Type Checker。我的减速器可以采取两种类型的动作。一个用于加载在初始应用程序加载时发生的所有首选项。当用户更新特定首选项时,会发生第二种操作类型。这是我的reducer的代码。我遇到问题的地方是当我尝试action.prefs.forEach时,流量会引发错误...'prefs': Property not found in 'object type'

// @flow
import {
  UPDATE_PREF,
  LOAD_PREFS_SUCCESS
} from '../actions/prefs';

export type actionType = {
  +type: string,
  prefs: Array<{_id: string, value: any}>
} | {
  +type: string,
  id: string,
  value: any
};

export default (state: stateType = {}, action: actionType) => {
  switch (action.type) {
    case LOAD_PREFS_SUCCESS: {
      const newState = {};
      action.prefs.forEach(p => {
        newState[p._id] = p.value;
      });
      return newState;
    }
    case UPDATE_PREF: {
      return { ...state, [action.id]: action.value };
    }
    default:
      return state;
  }
};

正如您所看到的,我有两种类型的操作。加载所有首选项时,该操作具有一系列首选项。 [ { _id: 'color', value: 'blue' } ]在更新单个首选项时,我会获得一个id和一个值。那么给我的两个具有不同属性的动作类型,如何让流程不会在动作流类型中抛出有关此变化的错误?

2 个答案:

答案 0 :(得分:1)

为了告诉Flow在disjoint union中选择哪种类型,+type必须是值而不是string。将您的actionType更改为使用值:

// @flow
import {
  UPDATE_PREF,
  LOAD_PREFS_SUCCESS
} from '../actions/prefs';

export type actionType = {
  +type: LOAD_PREFS_SUCCESS, // not just `string`
  prefs: Array<{_id: string, value: any}>
} | {
  +type: UPDATE_PREF,        // not just `string`
  id: string,
  value: any
};

答案 1 :(得分:1)

感谢@ ross-allen的一些指导,以及一些在flow.org上玩游戏,我找到了working solution

除此之外,除了罗斯回答添加+type: UPDATE_PREF之外,我还需要添加typeof。所以工作actionType是:

export type actionType = {
  +type: typeof LOAD_PREFS_SUCCESS,
  prefs: Array<{_id: string, value: any}>
} | {
  +type: typeof UPDATE_PREF,
  id: string,
  value: any
};

再次感谢@ ross-allen。