Typing a Class Component

In notebook:
FrontEndMasters Intermediate React
Created at:
2019-06-25
Updated:
2019-08-15
Tags:
React libraries JavaScript

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>
  );
}