Reputation: 11969
I have this container
export interface State {
email: string
}
const mapStateToProps = (state: State) => ({
email: state.email,
})
const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
onChange: (name: string, value: string) => dispatch(/*...*/),
})
export default connect(mapStateToProps, mapDispatchToProps)(Login)
and this component
export interface LoginProps {
email: string
onChange: (name: string, value: string) => void
}
const Login = (props: LoginProps) => (
<p>Render something here</p>
)
Is there a way to infer the type of the login properties based on the Container
definition so I don't have to manually define LoginProps
?
Upvotes: 1
Views: 81
Reputation: 4039
There are good type definitions for connect
, so the types of the props passed to the wrapped component can be inferred. If you wrote the container/component like this...
export interface State {
email: string
}
const stateToProps = (state: State) => ({
email: state.email
})
const dispatchToProps = (dispatch: Dispatch<Action>) => ({
onChange: (name: string, value: string) => dispatch(/*...*/)
})
const BlahBlah = connect(stateToProps, dispatchToProps)(({ email, onChange }) => (
<div />
));
email
and onChange
are typed correctly without additional annotation.
However, when you write the Login
component separately, without type annotation...
const Login = (props) => (
<p>Render something here</p>
)
the type of props
cannot be inferred. This is because in addition to passing Login
to connect
, you could also call it directly. For example, I could write in a component:
render() {
return (
<Login unrelated="a string" typescript="cool" />
);
}
Without annotation on the Login component, there is no way for the compiler to know which of the invocations of Login
(the connected one, or my direct rendering) provides the correct props. Without annotation then the compiler can only type props as any
, so we lose type-safety.
Upvotes: 1