export interface UserActions extends Action {
    type: UserKind;
    payload: UserPayload;
}
..TypeScript will raise an error on combineReducers:

To fix the compilation error, make the Redux action property be optional:
export interface UserActions extends Action {
    type: UserKind;
    payload?: UserPayload;
}
Result:

However, TypeScript won't be able to catch missed properties, it won't raise an error that we didn't pass the payload property on User 6:

To fix that, remove the optional indicator on Redux action:
export interface UserActions extends Action {
    type: UserKind;
    payload: UserPayload;
}
Result, TypeScript is now able to catch missed properties:

However, we are back to this error on combineReducers:

To comply with combineReducers requirement of Reducer actions containing just a type property only, create another interface that has optional properties (e.g., payload), and use that for the Redux reducer's action parameter (UserActionsNoPayload). And then on UserActions, inherit UserActionsNoPayload from UserActions:

Now, no more combineReducers compilation error, and the compiler is still able to catch missed properties:

Here are the TypeScript definitions for the routeToUser:
export interface StateProps {
    user: Dto.Client.User;
    component: Component;
    counter: Dto.Client.Counter;
}
export interface ActionProps {
    routeToUser: UserDispatcher;
    doCounter: CounterDispatcher;
}
interface Props extends StateProps, ActionProps {
}
export type Dispatcher = (action: UserActions | CounterActions) => void;
export type UserDispatcher = (action: UserActions) => void;
export type CounterDispatcher = (action: CounterActions) => void;
export default class ReduxFirstRouterApp extends React.Component<Props, {}> {
And here is how are the states and dispatchers are mapped as properties to a component via Redux's connect:
const mapStateToProps = ({user, component, counter}: StateProps) => ({user, component, counter});
const mapDispatchToProps = (dispatch: Dispatcher): ActionProps => ({
    routeToUser: (action: UserActions) => dispatch(action),
    doCounter: (action: CounterActions) => dispatch(action)
});
this.AppContainer = connect(mapStateToProps, mapDispatchToProps)(ReduxFirstRouterApp);
Happy Coding!
P.S.
At first, I tried creating UserActions with complete properties, and then made UserActionsNoPayload inherits UserActions and define payload as optional on UserActionsNoPayload; however, it's a compiler error:

 
No comments:
Post a Comment