function removeDestructuredPropTypeStatements()

in transforms/React-PropTypes-to-prop-types.js [145:213]


  function removeDestructuredPropTypeStatements(j, root) {
    let hasModifications = false;

    root
      .find(j.ObjectPattern)
      .filter(path => {
        const init = path.parent.node.init;
        if (!init) {
          return false;
        }
        if (
          !(
            init.name === 'React' || // const { PropTypes } = React
            (init.type === 'CallExpression' &&
              init.callee.name === 'require' &&
              init.arguments.length &&
              init.arguments[0].value === 'react')
          )
          // const { PropTypes } = require('react')
        ) {
          return false;
        }
        return path.node.properties.some(
          property => property.key.name === 'PropTypes'
        );
      })
      .forEach(path => {
        hasModifications = true;

        // Find any nested destructures hanging off of the PropTypes node
        const nestedPropTypesChildren = path.node.properties.find(
          property =>
            property.key.name === 'PropTypes' &&
            property.value.type === 'ObjectPattern'
        );

        // Remove the PropTypes key
        path.node.properties = path.node.properties.filter(property => {
          if (property.key.name === 'PropTypes') {
            if (property.value && property.value.type === 'Identifier') {
              localPropTypesName = property.value.name;
            }
            return false;
          } else {
            return true;
          }
        });

        // Add back any nested destructured children.
        if (nestedPropTypesChildren) {
          // TODO: This shouldn't just use a template string but the `ast-types` docs were too opaque for me to follow.
          const propTypeChildren = nestedPropTypesChildren.value.properties
            .map(property => property.key.name)
            .join(', ');
          const destructureStatement = j.template.statement([
            `const { ${propTypeChildren} } = ${localPropTypesName};`
          ]);

          j(path.parent.parent).insertBefore(destructureStatement);
        }

        // If this was the only property, remove the entire statement.
        if (path.node.properties.length === 0) {
          path.parent.parent.replace('');
        }
      });

    return hasModifications;
  }