Skip to content

Commit

Permalink
Fix required prop types for classes with annotated methods.
Browse files Browse the repository at this point in the history
The `react/prop-types` rule incorrectly considers  flow type
annotations on class methods with arguments named `props` as
prop type declarations for the class, even though flow itself
gives them no such weight.

When a react component is defined as a class extending `React.Component`,
and it defines a method that takes an annotated argument named `props`,
then, even though flow still thinks the props have `any` type, the
`prop-types` rule will not produce 'missing in props validation' errors.

A pattern that gets used a lot in React components is as follows:
```javascript
type Props = {...};
class Comp extends React.Component {
  constructor(props: Props) {
    super(props);
    // do something...
  }

  // ...
}
```
which makes this especially nefarious.
  • Loading branch information
Ethan Goldberg committed May 26, 2017
1 parent ccb213d commit 6e8f543
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/rules/prop-types.js
Expand Up @@ -868,7 +868,12 @@ module.exports = {

ArrowFunctionExpression: handleStatelessComponent,

FunctionExpression: handleStatelessComponent,
FunctionExpression: function(node) {
if (node.parent.type === 'MethodDefinition') {
return;
}
handleStatelessComponent(node);
},

MemberExpression: function(node) {
var type;
Expand Down
33 changes: 33 additions & 0 deletions tests/lib/rules/prop-types.js
Expand Up @@ -1115,6 +1115,20 @@ ruleTester.run('prop-types', rule, {
'}'
].join('\n'),
parser: 'babel-eslint'
}, {
code: [
'type Props = {',
' name: string,',
'};',
'class Hello extends React.Component {',
' props: Props;',
' render() {',
' const {name} = this.props;',
' return name;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint'
}, {
code: [
'Card.propTypes = {',
Expand Down Expand Up @@ -1405,6 +1419,25 @@ ruleTester.run('prop-types', rule, {

invalid: [
{
code: [
'type Props = {',
' name: string,',
'};',
'class Hello extends React.Component {',
' foo(props: Props) {}',
' render() {',
' return this.props.name;',
' }',
'}'
].join('\n'),
errors: [{
message: '\'name\' is missing in props validation',
line: 7,
column: 23,
type: 'Identifier'
}],
parser: 'babel-eslint'
}, {
code: [
'var Hello = createReactClass({',
' render: function() {',
Expand Down

0 comments on commit 6e8f543

Please sign in to comment.