Typing a Class Component
https://frontendmasters.com/courses/intermediate-react-v2/typing-a-class-component/
Fixing Details.js
// **** Details.tsx ****
// just showing the lines that were changed
import Carousel from './Carousel' // shows error, because
// this dependency is not typed yet
// for class components in React,
// you have to tell it what type of
// component it's going to get
// class Details extends React.Component {
class Details extends React.Component<RouteComponentProps> {
// (above line), it grabbed the `RouteComponentProps` from
// Reach router
// then add the type of parameters this function will receive
// it's {id: string}, since we are in the Details page
// and we do need an id to be able to render
class Details extends React.Component<RouteComponentProps<{id: string}>> {
// you can state that these are public functions
public state = { loading: true, showModal: false}
// you could do
private thing = 'blah' // TypeScript would not let others call this
// we need to set the types for other variables used later down in the code
// this is continued from the above line...
public state = { loading: true, showModal: false, name: '', animal: '', location: '', description: '',
media: [] as Photo[], // Photo is imported from `@frontendmasters/pet`
// if you don't give the type of the array, just an empty []
// then TypeScript will set it as `never[]` meaning,
// you should never touch it
url: '', breed:''}
// this solution only works with public class properties, otherwise you need to add them the call signature:
class Details extends React.Component<RouteComponentProps<{id: string}... add types here>> {
// next step, is to decide the case when
// no id is provided
...
componentDidMount() {
// so add this check here:
if(!this.props.id) {
navigate('/')
return
}
// now, pet.animal expects a number
pet
//.animal(this.props.id) // this should be a number type:
.animal(+this.props.id) // with the `+`, it's a number
// now, here ↴ we're using the type definitions from
// index.dts and VSCode will jump to it
.then(({animal}) => {
this.setState({
name: animal.name // you can can click on animal in VSCode and see the type definition
})
})
// set the Error type:
.catch((err: Error) => this.setState({error: err}))
}
}
// then finally set the export type
export default function DetailsErrorBoundary(
// set the type of argument it expects
props: RouteComponentProps<{ id: string }>
) {
return (
<ErrorBoundary>
<Details {...props} />
</ErrorBoundary>
);
}