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;
}