Reputation: 841
I am using redux/connect to get state and actions creators as props in my component. This, however, causes an error with Typescript when rendering the component as the props i'm receiving via connect are not explicitly written.
Is there a way to get around this without making the types optional or is there something else I am missing?
//FetchData Component
import React, {Component} from 'react';
import { connect } from "react-redux";
import {
getData,
filterMaterial,
filterSize,
resetMap
} from "../js/actions/index";
import { MapProperties } from '../types/state';
import { Appstate } from '../js/store';
type DispatchProps = {
getData: () => void,
filterMaterial: (name:string) => void,
filterSize: (name:string) => void,
resetMap: () => void
}
type Props = DispatchProps & LinkStateProps
class FetchData extends Component<Props> {
constructor(props: Props) {
super(props);
this.handleReset = this.handleReset.bind(this)
}
handleReset = () => {
if(this.props.resetMap) this.props.resetMap();
}
componentDidMount() {
if (this.props.getData) this.props.getData()
}
render() {
return (
...
);
}
}
type LinkStateProps = {
geoJSON: MapProperties,
mapJSON: MapProperties
}
const mapStateToProps = (state: Appstate, props:Props):LinkStateProps => {
return {
geoJSON: state.geoJSON,
mapJSON: state.mapJSON
};
};
export default connect(mapStateToProps, {
getData,
filterMaterial,
filterSize,
resetMap
})(FetchData);
//App Component
import React from 'react';
import './App.scss';
import FetchData from './components/FetchData';
function App() {
return (
<div className="App">
//error = Type '{}' is missing the following properties from type 'DispatchProps': getData, filterMaterial, filterSize, resetMap
<FetchData />
</div>
);
}
export default App;
Upvotes: 1
Views: 143
Reputation: 2310
It's because you're passing Props
into your mapToState
function.
try:
- const mapStateToProps = (state: Appstate, props:Props):LinkStateProps => {
+ const mapStateToProps = (state: Appstate):LinkStateProps => {
return {
geoJSON: state.geoJSON,
mapJSON: state.mapJSON
};
};
The second argument to mapToState
is an optional ownProps
argument that is only needed if you need any of the component's "own" props (not connected props) to create the proper mapping from state to props. Providing Props
as you did makes TypeScript assume that those props must be provided explicitly when using the component, hence the error you were seeing.
Also, you might consider using some built-in features that TypeScript offers to save you from typing things that TypeScript can infer types from automatically.
Consider this:
import React, {Component} from 'react';
import { connect } from "react-redux";
import {
getData,
filterMaterial,
filterSize,
resetMap
} from "../js/actions/index";
import { MapProperties } from '../types/state';
import { Appstate } from '../js/store';
const mapStateToProps = (state: Appstate) => ({
geoJSON: state.geoJSON,
mapJSON: state.mapJSON
});
const dispatchProps = {
getData,
filterMaterial,
filterSize,
resetMap
}
// You could do:
// type LinkStateProps = ReturnType<typeof mapStateToProps>;
// type DispatchProps = typeof dispatchProps;
// type Props = LinkStateProps & DispatchProps;
// or in one line:
type Props = ReturnType<typeof mapStateToProps> & typeof dispatchProps;
class FetchData extends Component<Props> {
constructor(props: Props) {
super(props);
this.handleReset = this.handleReset.bind(this)
}
handleReset = () => {
if(this.props.resetMap) this.props.resetMap();
}
componentDidMount() {
if (this.props.getData) this.props.getData()
}
render() {
return (
<p>something</p>
);
}
}
export default connect(mapStateToProps, dispatchProps)(FetchData);
Creating an object named dispatchProps
(which you do anyway to supply to connect
) lets you use Typescript's typeof
operator to auto-generate the type signature. And since mapStateToProps
returns an object, you can use ReturnType<typeof mapStateToProps>
to get the type signature of that object. Combining these two with the '&' operator gives you your Props
type. It's essentially a more concise (and less error-prone) way to do the exact same thing you were doing.
Upvotes: 2