Stack Exchange
How to use PropTypes.shape with Typescript
I'm refactoring a React application from Javascript to Typescript but I'm having some troubles migrating especially the shape PropType. My code looks like this right now:
import React from 'react';
import PropTypes from 'prop-types';

interface FooterProps {
  labels: FooterLabels;
}

interface FooterLabels {
  body: string;
}

const Footer: React.FC<FooterProps> = ({ labels }) => (
  <div className="footer">
    {/* ... */}
  </div>
);

Footer.propTypes = {
  labels: PropTypes.shape({
    body: PropTypes.string.isRequired
  }).isRequired
};

export default Footer;

But I'm getting an error in the PropTypes:
Type 'Validator<InferProps<{ body: Validator<string>; }>>' is not assignable to type 'Validator<FooterLabels>'.
  Type 'InferProps<{ body: Validator<string>; }>' is not assignable to type 'FooterLabels'.
    Property 'body' is optional in type 'InferProps<{ body: Validator<string>; }>' but required in type 'FooterLabels'.ts(2322)
FooterAppPromo.tsx(5, 3): The expected type comes from property 'labels' which is declared here on type 'WeakValidationMap<FooterProps>'

I'm new to Typescript so sometimes I don't really know what I'm doing, but I tried to do stuff like:
Footer.propTypes = {
  labels: PropTypes.shape<FooterLabels>({
    body: PropTypes.string.isRequired
  }).isRequired
};

But I'm getting the errors. I tried searching for example implementations but I couldn't find any.
EDIT
Typescript types and PropTypes are not the same thing. You can easily write an example where a Typescript validation passes but you still get a PropTypes warning (e.g. an external API that returns a number where should be a string). Here's two articles explaining why:

PropTypes in a TypeScript React Application
https://fettblog.eu/typescript-react/prop-types/

So my question is how can I make nested PropTypes objects (PropTypes.shape() or maybe PropTypes.objectOf()) work with TypeScript? 

I think only interface and React.FC<FooterProps> are enough. You don't need propTypes on React with Typescript

@AnhNguyen I would argue that if you do that, only TS-aware consumer of your component can be used. I'm also looking for a solution in TS with propTypes. Right now, tsc errors out with: Type 'undefined' is not assignable to type 'MetaType'.

The PropTypes error is because you are trying to use a PropType.shape, the shape allows you to have optional values on your shape, and in this case, your interface is strict, which means you do not have any kind of optional value, and React.Validator is trying to infer your types behind with your interfaces and that makes the error appear.
In simple words, if you have a strict interface with non-optional values, instead of using PropType.shape you should use PropType.exact and that should prevent the error.
E.G:
Footer.propTypes = {
  labels: PropTypes.exact({
    body: PropTypes.string
  }).isRequired
};

For that reason on your error message appears

Property 'body' is optional in type 'InferProps<{ body: Validator; }>' but required in type 'FooterLabels'.ts(2322)

EDITED
This happens only because you are using on the component
const Footer: React.FC<FooterProps> = ({ labels }) => (
The FC ( FunctionComponent Interface ) looking into the interfaces is presented as
interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
    }

The line that we should highlight here is the propTypes?: WeakValidationMap<P>; This is the one that infers our types based on our PropTypes.
You have a second option to use types on React, but I do not recommend it, instead of using FC, you can use ReactNode type, but you will lose the inferences that you have on the FC interface type inferring.
E.G.
function Footer = ({ labels }:FooterProps): ReactNode => (

Actually you don't need propTypes here - labels got just one nested field body that is typeof FooterLabels. 
interface FooterProps {
  labels: {
     body: FooterLabels;
  };
}


interface FooterProps {
  labels: PropTypes.InferProps<{ body: string }>
}


Please don't post only code as an answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually of higher quality, and are more likely to attract upvotes.
