Using the React Context API, I've built this reducer:
export const usersReducer = (state: UsersState, action: UsersAction) => {
switch (action.type) {
case TOGGLE_MODAL: {
return {
...state,
isModalOpen: !state.isModalOpen
};
}
case CANCEL_REQUEST: {
return {
...state,
isCancelRequest: action.payload
};
}
case UPDATE_COMPANY: {
return {
...state,
companyId: action.payload
};
}
default: {
return state;
}
}
}
The associated Actions look like this:
// Note: `ActionType` = `string`
export const TOGGLE_MODAL: ActionType = 'TOGGLE_MODAL';
export const CANCEL_REQUEST: ActionType = 'CANCEL_REQUEST';
export const UPDATE_COMPANY: ActionType = 'UPDATE_COMPANY';
type ToggleModalAction = {type: typeof TOGGLE_MODAL};
type CancelRequestAction = {type: typeof CANCEL_REQUEST, payload: boolean};
type UpdateCompanyAction = {type: typeof UPDATE_COMPANY, payload: number};
export type UsersAction =
| ToggleModalAction
| CancelRequestAction
| UpdateCompanyAction;
On the two action.payload
instances, Flow is saying this:
Cannot get `action.payload` because property `payload` is missing in `ToggleModalAction`
I thought the way I defined my 3 "...Action" types, I could include payload
where warranted and exclude it where it's not needed, like in ToggleModalAction
.
Any ideas how to solve this?
By doing typeof TOGGLE_MODAL
, etc., the type
key of your UsersAction
type will always be string
. What you need in order to get type help from Flow's disjoint unions is the string literals themselves:
type ToggleModalAction = {type: 'TOGGLE_MODAL'};
type CancelRequestAction = {type: 'CANCEL_REQUEST', payload: boolean};
type UpdateCompanyAction = {type: 'UPDATE_COMPANY', payload: number};