diff --git a/lib/util/usedPropTypes.js b/lib/util/usedPropTypes.js index 12dd0d2fa8..27b7551e02 100755 --- a/lib/util/usedPropTypes.js +++ b/lib/util/usedPropTypes.js @@ -313,21 +313,21 @@ module.exports = function usedPropTypesInstructions(context, components, utils) } const propName = ast.getKeyValue(context, properties[k]); - // Get parent names in the right hand side of `const {foo} = props.a.b` - let currentNode = (node.parent && node.parent.init) || {}; - allNames = []; - while (currentNode.property && currentNode.property.name !== 'props') { - allNames.unshift(currentNode.property.name); - currentNode = currentNode.object; - } - allNames.push(propName); if (propName) { usedPropTypes.push({ - allNames, + allNames: parentNames.concat([propName]), name: propName, node: properties[k] }); } + + if ( + propName && + properties[k].type === 'Property' && + properties[k].value.type === 'ObjectPattern' + ) { + markPropTypesAsUsed(properties[k].value, parentNames.concat([propName])); + } } break; } diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 33524f6376..67853ec3ef 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -2457,6 +2457,21 @@ ruleTester.run('no-unused-prop-types', rule, { '};' ].join('\n'), parser: parsers.BABEL_ESLINT + }, { + code: ` + class Hello extends React.Component { + render() { + const {foo: {bar}} = this.props; + return
{bar}
; + } + } + Hello.propTypes = { + foo: PropTypes.shape({ + bar: PropTypes.string, + }) + }; + `, + options: [{skipShapeProps: false}] }, { // issue #933 code: [ diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 58f88c2a56..bbd1c07ba5 100755 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2412,6 +2412,47 @@ ruleTester.run('prop-types', rule, { column: 35, type: 'Identifier' }] + }, { + code: ` + class Hello extends React.Component { + render() { + const { foo: { bar } } = this.props; + return

{bar}

+ } + } + `, + errors: [ + {message: "'foo' is missing in props validation"}, + {message: "'foo.bar' is missing in props validation"} + ] + }, { + code: ` + class Hello extends React.Component { + render() { + const { foo: { bar } } = this.props; + return

{bar}

+ } + } + + Hello.propTypes = { + foo: PropTypes.shape({ + _: PropTypes.string, + }) + } + `, + errors: [ + {message: "'foo.bar' is missing in props validation"} + ] + }, { + code: ` + function Foo({ foo: { bar } }) { + return

{bar}

+ } + `, + errors: [ + {message: "'foo' is missing in props validation"}, + {message: "'foo.bar' is missing in props validation"} + ] }, { code: [ 'class Hello extends React.Component {',