I\'m having some trouble figuring out how to properly type Redux containers.
Consider a simple presentational component that might look like this:
in
I just use Partial, where Partial is a built-in TypeScript type defined as:
type Partial = {
[P in keyof T]?: T[P];
}
It takes an interface and makes every property in it optional.
Here's an example of a presentational/Redux-aware component pair I've written:
/components/ConnectionPane/ConnectionPane.tsx
export interface IConnectionPaneProps {
connecting: boolean;
connected: boolean;
onConnect: (hostname: string, port: number) => void;
}
interface IState {
hostname: string;
port?: number;
}
export default class ConnectionPane extends React.Component {
...
}
/containers/ConnectionPane/ConnectionPane.ts
import {connect} from 'react-redux';
import {connectionSelectors as selectors} from '../../../state/ducks';
import {connect as connectToTestEcho} from '../../../state/ducks/connection';
import {ConnectionPane, IConnectionPaneProps} from '../../components';
function mapStateToProps (state): Partial {
return {
connecting: selectors.isConnecting(state),
connected: selectors.isConnected(state)
};
}
function mapDispatchToProps (dispatch): Partial {
return {
onConnect: (hostname, port) => dispatch(connectToTestEcho(hostname, port))
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ConnectionPane) as any;
The presentational component props are non-optional - exactly as required for the presentation without any bearing on the corresponding "smart" component.
Meanwhile, mapStateToProps and mapDispatchToProps will allow me to assign a subset of the required presentational props in each function, while flagging any props not defined in the presentational props interface as an error.