Skip to content

Commit

Permalink
Add support for propTypes wrapped in a function
Browse files Browse the repository at this point in the history
PropTypes would previously get ignored if wrapped in forbidExtraProps.
  • Loading branch information
dustinsoftware committed Jun 16, 2017
1 parent 7e5863e commit 5770f29
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
3 changes: 2 additions & 1 deletion docs/rules/no-unused-prop-types.md
Expand Up @@ -47,13 +47,14 @@ This rule can take one argument to ignore some specific props during validation.

```js
...
"react/no-unused-prop-types": [<enabled>, { customValidators: <customValidator>, skipShapeProps: <skipShapeProps> }]
"react/no-unused-prop-types": [<enabled>, { customValidators: <customValidator>, skipShapeProps: <skipShapeProps>, propWrapperFunctions: <propWrapperFunctions> }]
...
```

* `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.
* `customValidators`: optional array of validators used for propTypes validation.
* `skipShapeProps`: In some cases it is impossible to accurately detect whether or not a `PropTypes.shape`'s values are being used. Setting this option to `true` will skip validation of `PropTypes.shape` (`true` by default).
* `propWrapperFunctions`: The names of any functions used to wrap the propTypes object, such as `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.

## Caveats

Expand Down
18 changes: 18 additions & 0 deletions lib/rules/no-unused-prop-types.js
Expand Up @@ -44,6 +44,13 @@ module.exports = {
},
skipShapeProps: {
type: 'boolean'
},
propWrapperFunctions: {
type: 'array',
items: {
type: 'string'
},
uniqueItems: true
}
},
additionalProperties: false
Expand All @@ -56,6 +63,8 @@ module.exports = {
var configuration = Object.assign({}, defaults, context.options[0] || {});
var skipShapeProps = configuration.skipShapeProps;
var customValidators = configuration.customValidators || [];
var propWrapperFunctions = new Set(configuration.propWrapperFunctions || []);

// Used to track the type annotations in scope.
// Necessary because babel's scopes do not track type annotations.
var stack = null;
Expand Down Expand Up @@ -722,6 +731,15 @@ module.exports = {
}
ignorePropsValidation = true;
break;
case 'CallExpression':
if (
propWrapperFunctions.has(propTypes.callee.name) &&
propTypes.arguments && propTypes.arguments[0]
) {
markPropTypesAsDeclared(node, propTypes.arguments[0]);
return;
}
break;
case null:
break;
default:
Expand Down
41 changes: 41 additions & 0 deletions tests/lib/rules/no-unused-prop-types.js
Expand Up @@ -2779,6 +2779,47 @@ ruleTester.run('no-unused-prop-types', rule, {
line: 10,
column: 8
}]
}, {
code: [
'class Hello extends Component {',
' componentDidUpdate (nextProps) {',
' if (nextProps.foo) {',
' return true;',
' }',
' }',
'}',
'Hello.propTypes = forbidExtraProps({',
' foo: PropTypes.string,',
' bar: PropTypes.string,',
'});'
].join('\n'),
errors: [{
message: '\'bar\' PropType is defined but prop is never used',
line: 10,
column: 8
}],
options: [{propWrapperFunctions: ['forbidExtraProps']}]
}, {
code: [
'class Hello extends Component {',
' propTypes = forbidExtraProps({',
' foo: PropTypes.string,',
' bar: PropTypes.string',
' });',
' componentDidUpdate (nextProps) {',
' if (nextProps.foo) {',
' return true;',
' }',
' }',
'};'
].join('\n'),
parser: 'babel-eslint',
errors: [{
message: '\'bar\' PropType is defined but prop is never used',
line: 4,
column: 10
}],
options: [{propWrapperFunctions: ['forbidExtraProps']}]
}
/* , {
// Enable this when the following issue is fixed
Expand Down

0 comments on commit 5770f29

Please sign in to comment.