diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 56b803bf7e..88be549151 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -430,7 +430,6 @@ module.exports = function propTypesInstructions(context, components, utils) { const component = components.get(componentNode); const declaredPropTypes = component && component.declaredPropTypes || {}; let ignorePropsValidation = component && component.ignorePropsValidation || false; - switch (propTypes && propTypes.type) { case 'ObjectTypeAnnotation': ignorePropsValidation = declarePropTypesForObjectTypeAnnotation(propTypes, declaredPropTypes); @@ -470,13 +469,18 @@ module.exports = function propTypesInstructions(context, components, utils) { } } if (propTypes && propTypes.parent && propTypes.property) { + if (!(propTypes === propTypes.parent.left && propTypes.parent.left.object)) { + ignorePropsValidation = true; + break; + } + const parentProp = context.getSource(propTypes.parent.left.object).replace(/^.*\.propTypes\./, ''); const types = buildReactDeclarationTypes( propTypes.parent.right, - propTypes.parent.left.object.property.name + parentProp ); types.name = propTypes.property.name; - types.fullName = propTypes.property.name; + types.fullName = [parentProp, propTypes.property.name].join('.'); types.node = propTypes.property; curDeclaredPropTypes[propTypes.property.name] = types; } else { diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 9222db7784..61bff0fee9 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -4642,6 +4642,29 @@ ruleTester.run('no-unused-prop-types', rule, { errors: [{ message: '\'age\' PropType is defined but prop is never used' }] + }, { + code: [ + 'class Hello extends React.Component {', + ' render() {', + ' return
Hello
;', + ' }', + '}', + 'Hello.propTypes = {', + ' a: PropTypes.shape({', + ' b: PropTypes.shape({', + ' })', + ' })', + '};', + 'Hello.propTypes.a.b.c = PropTypes.number;' + ].join('\n'), + options: [{skipShapeProps: false}], + errors: [{ + message: '\'a\' PropType is defined but prop is never used' + }, { + message: '\'a.b\' PropType is defined but prop is never used' + }, { + message: '\'a.b.c\' PropType is defined but prop is never used' + }] } /* , { diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 6a7e31ae6b..a879f05434 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -1939,6 +1939,24 @@ ruleTester.run('prop-types', rule, { } `, parser: 'babel-eslint' + }, + { + code: ` + const Slider = props => ( + + ); + + Slider.propTypes = RcSlider.propTypes; + ` + }, + { + code: ` + const Slider = props => ( + + ); + + Slider.propTypes = RcSlider.propTypes; + ` } ], @@ -2137,6 +2155,22 @@ ruleTester.run('prop-types', rule, { errors: [{ message: '\'a.b.c\' is missing in props validation' }] + }, { + code: [ + 'class Hello extends React.Component {', + ' render() {', + ' this.props.a.b.c;', + ' return
Hello
;', + ' }', + '}', + 'Hello.propTypes = {', + ' a: PropTypes.shape({})', + '};', + 'Hello.propTypes.a.b = PropTypes.shape({});' + ].join('\n'), + errors: [{ + message: '\'a.b.c\' is missing in props validation' + }] }, { code: [ 'class Hello extends React.Component {',