Tengo el siguiente fragmento de código, que recibe un objeto de historial como accesorio:
const ChildComponent = ({ history }) => ( <div className={styles.body}> <div className={styles.cta}> <FloatingActionButton onClick={() => history.push(routes[4].path)}> <span>Click me</span> </FloatingActionButton> </div> </div> );¿Cómo agrego una verificación de tipo para este accesorio de historial, que se recibe al envolver su padre con withRouter HOC ? Una forma en la que podría pensar es escribir algo como esto:
interface Props { history: { push(url: string): void; }; }Pero estoy seguro de que esta no es la forma correcta, porque el resto de las propiedades del objeto de la historia se están perdiendo.
¿Puede sugerir la forma correcta de hacer esto?
ACTUALIZADO el código basado en la respuesta de @Oblosys
import { withRouter, RouteComponentProps } from "react-router-dom"; interface Props extends RouteComponentProps<any> { /* Parent component's props*/ } class Parent extends React.Component<Props, {}> { render() { return <ChildComponent history={this.props.history} />; } } //Child component related stuff interface ChildComponentProps extends RouteComponentProps<any> {} const ChildComponent: React.SFC<ChildComponentProps> = (props) => ( <div className={styles.body}> <div className={styles.cta}> <FloatingActionButton onClick={() => history.push(routes[4].path)}> <span>Click me</span> </FloatingActionButton> </div> </div> ); function mapStateToProps(state: types.AppState) { /* related code */ } function mapDispatchToProps(dispatch: Redux.Dispatch<types.AppState>{ /* related code */ } export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Parent));Pero, ahora estoy recibiendo el siguiente error:
Type '{ history: History; }' is not assignable to type 'ChildComponentProps'. Property 'match' is missing in type '{ history: History; }'Puede usar la interfaz RouteComponentProps , que declara todos los accesorios pasados por withRouter :
import { RouteComponentProps } from 'react-router-dom'; .. interface ChildComponentProps extends RouteComponentProps<any> { /* other props for ChildComponent */ } const ChildComponent : React.SFC<ChildComponentProps> = ({ history }) => ( .. ); El parámetro de tipo para RouteComponentProps es el tipo de la propiedad params en match , por lo que no lo necesitará a menos que esté haciendo coincidir segmentos de ruta con nombre.
Alternativamente, si el history no proviene de withRouter sino que se pasa solo como accesorio, puede importar el tipo desde el history :
import { History } from 'history'; .. interface ChildComponentProps { history : History /* other props for ChildComponent */ } const ChildComponent : React.SFC<ChildComponentProps> = ({ history }) => ( .. );La solución más simple que encontré.
import { RouteComponentProps } from 'react-router-dom'; .... interface Foo{ history: RouteComponentProps["history"]; location: RouteComponentProps['location']; match: RouteComponentProps['match']; }Para React 16.8 con ganchos:
... import {withRouter, RouteComponentProps} from 'react-router-dom'; ... const ChildComponent: React.FunctionComponent<RouteComponentProps> = ({history}) => { ... }