29

I am trying to set up a typescript-react-eslint project and can't get past eslint error for this boilerplate component:

import * as React from "react";

interface ButtonProps {
  children?: React.ReactNode,
  onClick?: (e: any) => void,
}

const styles = {
  border: "1px solid #eee",
  borderRadius: 3,
  backgroundColor: "#FFFFFF",
  cursor: "pointer",
  fontSize: 15,
  padding: "3px 10px",
  margin: 10
};

const Button: React.FunctionComponent<ButtonProps> = props => (
  <button onClick={props.onClick} style={styles} type="button">
    {props.children}
  </button>
);

Button.defaultProps = {
  children: null,
  onClick: () => {}
};
export default Button;

The error is:

  19:26  error  'onClick' is missing in props validation   react/prop-types
  20:12  error  'children' is missing in props validation  react/prop-types

It seems like it is complaining about interface for html <button> is not defined? Otherwise it might be the Button component itself but should it not get type information from <ButtonProps> interface I pass there?

I tried explicitly setting children and onClick like this:

Button.propTypes = {
  children?: React.ReactNode,
  onClick?: (e: any) => void
};

it bypasses the eslint error but the component itself stops working. What am I doing wrong?

P.S. This is my .eslintrc.json

{
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/eslint-recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "settings": {
        "react": {
            "pragma": "React",
            "version": "detect"
        }
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
        "indent": [
            "error",
            2
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "double"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
}
3
  • Use default values inside arguments <ButtonProps> = ({ onClick: () => {}, children: null }) => ( Commented Dec 15, 2019 at 23:53
  • You don't need to define children in ButtonProps as React.FunctionComponent<T> already defines it as: children?: ReactNode. Also, you can use React.FC instead of the very verbose React.FunctionComponent Commented Dec 16, 2019 at 0:11
  • If I don't define children in ButtonProps, nothing changes: error still complains about both children and onClick. It seems like the interface is being ignored in const Button: React.FC<ButtonProps> = props => ... Commented Dec 16, 2019 at 0:17

5 Answers 5

25

This rule doesn't make sense with TypeScript because you already is checking types.

In this question you found a simple way to disable this rule, just add in your eslint configuration:

  rules: {
    'react/prop-types': 0
  }

to be more readable you can use "off" instead "0".

Sign up to request clarification or add additional context in comments.

Comments

24

I ended up rewriting the component as:

const Button = ({ children, onClick }: ButtonProps) => {
  return <button onClick={onClick} style={styles} type="button">
    {children}
  </button>;
};

The : React.FC<ButtonProps> part was ignored by eslint so I decided to provide prop types in a more straightforward way

Comments

6

eslint-plugin-react@^7.25.0 appears to have resolved the issue for those using React.FC<IProps> with react/prop-types validation rule.

So instead of

const Example: React.FC<IProps> = (props: IProps) => ...

This now works without warnings after the update

const Example: React.FC<IProps> = (props) => ...

1 Comment

if we use a generic type for components, we can't use React.FC, and when passing props explicitly like (props: Props) => , the warning will be shown again
5

More info to your answer..

Firstly both ways are correct for declaring types, But React.FC has some added benefits. https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/blob/master/README.md#function-components

enter image description here

And in your scenario you may be using eslint-react-plugin which has recommended rules 'plugin:react/recommended' for eslint ,
Rule to check proptypes is one among them, check typescript example. https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md

So react/prop-types rule will conflict with TS Interfaces, which is why it shows that error, once you add : ButtonProps, we don't have to provide React.FC

1 Comment

FYI that page you linked to has been updated to say "the general consensus today is that React.FunctionComponent (or the shorthand React.FC) is discouraged"
5

importing React solved my problem

import React from 'react';

1 Comment

anyone have an explanation of why this fixes the problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.