Typescript Errors while converting a React project

All we need is an easy explanation of the problem, so here it is.

This is specific to a React app I am converting from standard ES2015 to Typescript. In my .tsx files (converted from regular .js files) I am getting a couple of typescript errors I do not know how to solve.

The first is: error TS2339: Property 'propTypes' does not exist on type 'typeof App'.

This applies to:

App.propTypes = {
  actions: PropTypes.object.isRequired,
  fuelSavingsAppState: PropTypes.object.isRequired
};

I tried creating an interface above that code that defined App like:

interface App {
    propTypes?: any;
}

But this had no effect. Clearly I am new to Typescript so what am I missing?

The other error is:

error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Element'

and this applies to:

{settings.necessaryDataIsProvidedToCalculateSavings ? <FuelSavingsResults savings={settings.savings} /> : null}

The error specifically refers to the bit about <FuelSavingsResults

At a complete loss as to where to even start with that. Any suggestions are most welcome.


in case it helps, the definition for FuelSavingsResults starts like:

let FuelSavingsResults = (props) => {
    let savingsExist = NumberFormatter.scrubFormatting(props.savings.monthly) > 0;
    let savingsClass = savingsExist ? 'savings' : 'loss';
    let resultLabel = savingsExist ? 'Savings' : 'Loss';

and then has a regular React render method that follows, but I don’t think that will matter.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

error TS2339: Property ‘propTypes’ does not exist on type ‘typeof App’.

Instead of

class App extends React.Component{
}
App.propTypes = {
  actions: PropTypes.object.isRequired,
  fuelSavingsAppState: PropTypes.object.isRequired
};

Use a static property.

class App extends React.Component{
    static propTypes = {
      actions: PropTypes.object.isRequired,
      fuelSavingsAppState: PropTypes.object.isRequired
    };
}

error TS2605: JSX element type ‘Element’ is not a constructor function for JSX elements.
Property ‘render’ is missing in type ‘Element’

This was a bug in the compiler that has since been fixed : https://github.com/Microsoft/TypeScript/issues/6349 Alternative provide type annotations for props. 🌹

Method 2

Is propTypes really required? Won’t interface check at compile time what propTypes check in runtime?

interface IApp{
  actions:any;
  fuelSavingsAppState: (props:any)=> void;
}

class App extends React.Component<IApp,{}>{
}

or if you are using dumb components

const App = ({actions,  fuelSavingsAppState }:IApp):React.ReactElement<{}> => (
  <div>
   What Ever you want to do with the props 
  </div>
)

Note: If you are using object please create an interface for the same. Like actions as of now given as any which should be ideally an interface.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply