In my app, I have a number of different actions that may or may not affect the same part of the state. To simplify the example I created this small code:
// @ts-ignore
import { handleActions } from 'redux-actions';
interface Thing{
id: number
}
interface ActionA {
type: string;
payload?: Thing;
}
interface ActionB {
type: string;
payload?: Thing[];
}
interface State {
things: Thing[];
}
const someActionA: ActionA = {
payload: { id: 35 },
type: 'actionA'
};
const someActionB: ActionB = {
payload: [{ id: 35 }],
type: 'actionB'
};
const reducer = handleActions({
[someActionA.type]: (state: State, action: ActionA) => state,
[someActionB.type]: (state: State, action: ActionB) => state,
}, {things: []});
Without a type checking it would all work fine. However, the TS compiler complains in this case. because the types of payload are incompatible.
I am fighting with the types for a while now and every type hitting some other wall. What is the correct way to solve it?
The error that I am getting:
TS2769: No overload matches this call. Overload 1 of 3, '(reducerMap: ReducerMap, initialState: State, options?: Options | undefined): ReduxCompatibleReducer', gave the following error. Argument of type '{ [x: string]: ((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State); }' is not assignable to parameter of type 'ReducerMap'. Index signatures are incompatible. Type '((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State)' is not assignable to type 'ReducerMapValue'. Type '(state: State, action: ActionA) => State' is not assignable to type 'ReducerMapValue'. Type '(state: State, action: ActionA) => State' is not assignable to type 'Reducer'. Types of parameters 'action' and 'action' are incompatible. Type 'Action' is not assignable to type 'ActionA'. Types of property 'payload' are incompatible. Property 'id' is missing in type 'State' but required in type 'Thing'. Overload 2 of 3, '(reducerMap: ReducerMap, initialState: State, options?: Options | undefined): ReduxCompatibleReducer', gave the following error. Argument of type '{ [x: string]: ((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State); }' is not assignable to parameter of type 'ReducerMap'. Index signatures are incompatible. Type '((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State)' is not assignable to type 'ReducerMapValue'. Type '(state: State, action: ActionB) => State' is not assignable to type 'ReducerMapValue'. Type '(state: State, action: ActionB) => State' is not assignable to type 'Reducer'. Types of parameters 'action' and 'action' are incompatible. Type 'Action' is not assignable to type 'ActionB'. Types of property 'payload' are incompatible. Type 'Thing | undefined' is not assignable to type 'Thing[] | undefined'. Type 'Thing' is missing the following properties from type 'Thing[]': length, pop, push, concat, and 28 more. Overload 3 of 3, '(reducerMap: ReducerMapMeta, initialState: State, options?: Options | undefined): ReduxCompatibleReducerMeta', gave the following error. Argument of type '{ [x: string]: ((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State); }' is not assignable to parameter of type 'ReducerMapMeta'. Index signatures are incompatible. Type '((state: State, action: ActionA) => State) | ((state: State, action: ActionB) => State)' is not assignable to type 'ReducerMapMeta | ReducerMeta | ReducerNextThrowMeta'. Type '(state: State, action: ActionB) => State' is not assignable to type 'ReducerMapMeta | ReducerMeta | ReducerNextThrowMeta'. Type '(state: State, action: ActionB) => State' is not assignable to type 'ReducerMeta'. Types of parameters 'action' and 'action' are incompatible. Type 'ActionMeta' is not assignable to type 'ActionB'. Types of property 'payload' are incompatible. Type 'Thing | undefined' is not assignable to type 'Thing[] | undefined'. Type 'Thing' is not assigna
ble to type 'Thing[]'.