eslint-plugin-react: Prop type object if forbidden [react/forbid-prop-types]

Hi I have this component:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

const styles = theme => ({
  root: {
    ...theme.mixins.gutters(),
    paddingTop: theme.spacing.unit * 2,
    paddingBottom: theme.spacing.unit * 2,
  },
});

function PaperSheet(props) {
  const { classes } = props;
  const { title, data } = props;

  return (
    <div>
      <Paper className={classes.root} elevation={1}>
        <Typography variant="h5" component="h3">
          {title}
        </Typography>
        <Typography component="p">
          {data}
        </Typography>
      </Paper>
    </div>
  );
}

PaperSheet.propTypes = {
  classes: PropTypes.object.isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

export default withStyles(styles)(PaperSheet);

package.json:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start:dev": "webpack && webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@material-ui/core": "^3.6.1",
    "mathjs": "^5.3.1",
    "prop-types": "^15.6.2",
    "react": "^16.7.0-alpha.2",
    "react-dom": "^16.7.0-alpha.2"
  },
  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/preset-react": "^7.0.0",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.4",
    "eslint": "^5.9.0",
    "eslint-config-airbnb": "^17.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^6.1.2",
    "eslint-plugin-react": "^7.11.1",
    "webpack": "^4.27.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

.eslint.rc

module.exports = {
    "extends": [
        "airbnb",
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        }
      }
};

I got eslint errors for the PropTypes object:

PaperSheet.propTypes = {
  classes: PropTypes.object.isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

The error mentions: Prop type object is forbidden How can I fix that?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 14
  • Comments: 28 (11 by maintainers)

Most upvoted comments

You can define as following: dataOptions: PropTypes.objectOf(PropTypes.object()),

Easiest way: PropTypes.shape({}).isRequired

Update (New solution): PropTypes.oneOfType([PropTypes.object]).isRequired

You can define as following: dataOptions: PropTypes.objectOf(PropTypes.object()),

PropTypes.objectOf(PropTypes.object), PropTypes.object() is not callable.

By using shape or objectOf instead of object. In this case, PropTypes.shape({ root: PropTypes.string.isRequired })

PaperSheet.propTypes = {
  classes: PropTypes.InstanceOf(Array).isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

This is another solution you can solve the issue

If anyone is still hitting this issue from google (it’s the top result) - here’s a quick rundown…

This ESLint rule is forbidding prop types of OBJECT because they are very unspecific. Just like our function will probably expect to use certain properties from an object our prop types should expect these too.

The way to do this is with the SHAPE function - this tells proptypes to expect an object containing at least the defined properties.

This doesn’t mean you should list every property of the inbound object, a good practice is to at least list the properties used in the specific component.

e.g.

ProfileScreen.propTypes = {
    user: PropTypes.shape({username: PropTypes.string, email: PropTypes.string})
}

Would check the incoming object contains username and email that are strings.

Hope this is helpful to someone

The rule is to forbid certain propTypes from being used.

A very common way to configure it is to forbid object and array, because these are very non specific types. Instead, you’d want to use objectOf and arrayOf, and provide a propType for the contents of the array.

Simply use this rule

PropTypes.objectOf(PropTypes.any).isRequired

PropTypes.any indicates the values of the object can be of any type.

Using instanceOf (correction from InstanceOf) is unreliable at best, however. If you want to bypass the spirit of the rule, use an override comment.

@EzequielDeSimone-Reflektion the inner one should be a shape tho, not object.

This will solved your prob.

PropTypes.oneOfType([PropTypes.object]).isRequired

You can define as following: dataOptions: PropTypes.objectOf(PropTypes.object()),

PropTypes.objectOf(PropTypes.object), PropTypes.object() is not callable.

chrome warning as follow: Warning: Failed prop type: Invalid prop children.$$typeof of type symbol supplied to App, expected object.

@josh-wer the point of this rule is that you shouldn’t ever use any - use a more descriptive propType.

Okay @ljharb , I get that. Out of curiosity can u explain how that solution is different from PropTypes.objectOf(PropTypes.object) or PropTypes.oneOfType([PropTypes.object]).isRequired suggested by other answers based on the condition you gave. Assuming the prop value is of the shape

{
  name: "John Doe",
  age: 28,
  isAdmin: false
}