typescript + redux: exclude redux props in parent component
You need to split up your props - you'll need a DispatchProps
, StateProps
, and an OwnProps
type. You'll also have to use TypeScript's generics with connect
DispatchProps
are your action creators.StateProps
are your state props (duh) - these come frommapStateToProps
- the return type of that function should match this type.OwnProps
are props which are accepted (and perhaps expected) by your component. Optional props should be marked as optional in the interface.
The way I do it (without decorators, but i'm sure it applies here) is
interface ComponentDispatchProps {
doSomeAction: typeof someAction;
}
interface ComponentStateProps {
somethingFromState: any;
}
interface ComponentOwnProps {
somethingWhichIsRequiredInProps: any;
somethingWhichIsNotRequiredInProps?: any;
}
// not necessary to combine them into another type, but it cleans up the next line
type ComponentProps = ComponentStateProps & ComponentDispatchProps & ComponentOwnProps;
class Component extends React.Component<ComponentProps, {}> {...}
function mapStateToProps(state, props) {
return { somethingFromState };
}
export default connect<ComponentStateProps, ComponentDispatchProps, ComponentOwnProps>(
mapStateToProps,
mapDispatchToProps
)(Component);
I think you have to use @connect<StateProps, DispatchProps, OwnProps>
which will decorate and return a class which accepts OwnProps
.
If you look at connect
s implementation in TS
export declare function connect<TStateProps, TDispatchProps, TOwnProps>(...): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps>
interface ComponentDecorator<TOriginalProps, TOwnProps> {
(component: ComponentClass<TOriginalProps> | StatelessComponent<TOriginalProps>): ComponentClass<TOwnProps>;
}
connect<...>
returns a ComponentDecorator
, which, when passed the component (in your case this is done transparently when transpiling the decorator out), regardless of StateProps
, and DispatchProps
returns a component which expects OwnProps
.
connect
(non-generic) returns InferableComponentDecorator
export interface InferableComponentDecorator {
<P, TComponentConstruct extends (ComponentClass<P> | StatelessComponent<P>)>(component: TComponentConstruct): TComponentConstruct;
}
which attempts to infer the props based on the props supplied to the component, which in your case is the combination of all props (OwnProps
becomes ComponentProps
from above).