diff --git a/lib/rules/no-unused-prop-types.js b/lib/rules/no-unused-prop-types.js
index 0471913737..a5afea72af 100644
--- a/lib/rules/no-unused-prop-types.js
+++ b/lib/rules/no-unused-prop-types.js
@@ -791,6 +791,13 @@ module.exports = {
types.name = key;
types.node = value;
declaredPropTypes.push(types);
+ // Handle custom prop validators using props inside
+ if (
+ value.type === 'ArrowFunctionExpression'
+ || value.type === 'FunctionExpression'
+ ) {
+ markPropTypesAsUsed(value);
+ }
});
break;
case 'MemberExpression':
diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js
index 62ef6094c0..e8b3e8e210 100644
--- a/tests/lib/rules/no-unused-prop-types.js
+++ b/tests/lib/rules/no-unused-prop-types.js
@@ -829,10 +829,10 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsA = { a: string }
type PropsB = { b: string }
type Props = PropsA & PropsB;
-
+
class MyComponent extends React.Component {
props: Props;
-
+
render() {
return
{this.props.a} - {this.props.b}
}
@@ -848,7 +848,7 @@ ruleTester.run('no-unused-prop-types', rule, {
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar} - {this.props.zap}
}
@@ -864,7 +864,7 @@ ruleTester.run('no-unused-prop-types', rule, {
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar} - {this.props.zap}
}
@@ -876,12 +876,12 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsB = { foo: string };
type PropsC = { bar: string };
type Props = PropsB & {
- zap: string
+ zap: string
};
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar} - {this.props.zap}
}
@@ -893,12 +893,12 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsB = { foo: string };
type PropsC = { bar: string };
type Props = {
- zap: string
+ zap: string
} & PropsB;
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar} - {this.props.zap}
}
@@ -2208,6 +2208,78 @@ ruleTester.run('no-unused-prop-types', rule, {
`,
settings: {react: {flowVersion: '0.53'}},
parser: 'babel-eslint'
+ }, {
+ // Issue #1068
+ code: `
+ class MyComponent extends Component {
+ static propTypes = {
+ validate: PropTypes.bool,
+ options: PropTypes.array,
+ value: ({options, value, validate}) => {
+ if (!validate) return;
+ if (options.indexOf(value) < 0)
+ throw new Errow('oops');
+ }
+ }
+
+ render() {
+ return
+ {this.props.options.map(option =>
+ - {option}
+ )}
+
+ }
+ }
+ `,
+ parser: 'babel-eslint'
+ }, {
+ // Issue #1068
+ code: `
+ class MyComponent extends Component {
+ static propTypes = {
+ validate: PropTypes.bool,
+ options: PropTypes.array,
+ value: function ({options, value, validate}) {
+ if (!validate) return;
+ if (options.indexOf(value) < 0)
+ throw new Errow('oops');
+ }
+ }
+
+ render() {
+ return
+ {this.props.options.map(option =>
+ - {option}
+ )}
+
+ }
+ }
+ `,
+ parser: 'babel-eslint'
+ }, {
+ // Issue #1068
+ code: `
+ class MyComponent extends Component {
+ static propTypes = {
+ validate: PropTypes.bool,
+ options: PropTypes.array,
+ value({options, value, validate}) {
+ if (!validate) return;
+ if (options.indexOf(value) < 0)
+ throw new Errow('oops');
+ }
+ }
+
+ render() {
+ return
+ {this.props.options.map(option =>
+ - {option}
+ )}
+
+ }
+ }
+ `,
+ parser: 'babel-eslint'
}
],
@@ -2796,10 +2868,10 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsA = { a: string }
type PropsB = { b: string }
type Props = PropsA & PropsB;
-
+
class MyComponent extends React.Component {
props: Props;
-
+
render() {
return {this.props.a}
}
@@ -2818,7 +2890,7 @@ ruleTester.run('no-unused-prop-types', rule, {
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar}
}
@@ -2833,12 +2905,12 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsB = { foo: string };
type PropsC = { bar: string };
type Props = PropsB & {
- zap: string
+ zap: string
};
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar}
}
@@ -2853,12 +2925,12 @@ ruleTester.run('no-unused-prop-types', rule, {
type PropsB = { foo: string };
type PropsC = { bar: string };
type Props = {
- zap: string
+ zap: string
} & PropsB;
class Bar extends React.Component {
props: Props & PropsC;
-
+
render() {
return {this.props.foo} - {this.props.bar}
}