An Interesting task.
I start with:
import React from "react";
import * as PropTypes from "prop-types";
function Hello(props) {
const { boo, foo } = props;
return (
<div>
<h1>{boo}</h1>
<h2>{foo}</h2>
</div>
);
}
Hello.propTypes = {
boo: PropTypes.string,
foo: PropTypes.number
};
export default Hello;
I found this article https://blog.jim-nielsen.com/2020/proptypes-outside-of-react-in-template-literal-components/ with function:
/**
* Anytime you want to check prop types, wrap in this
* @param {function} Component
* @param {Object} propTypes
* @return {string} result of calling the component
*/
function withPropTypeChecks(Component) {
return props => {
if (Component.propTypes) {
Object.keys(props).forEach(key => {
PropTypes.checkPropTypes(
Component.propTypes,
props,
key,
Component.name
);
});
}
return Component(props);
};
}
Then I wrote another one:
const getPropsInfo = (component) => {
const result = {};
const mock = Object.keys(component.propTypes).reduce(
(acc, p) => ({ ...acc, [p]: Symbol() }),
{}
);
const catching = (arg) => {
const [, , prop, type] = `${arg}`.match(
/Warning: Failed (.*) type: Invalid .* `(.*)` of type `symbol` supplied to.*, expected `(.*)`./
);
result[prop] = type;
};
const oldConsoleError = console.error.bind(console.error);
console.error = (...arg) => catching(arg);
withPropTypeChecks(component)(mock);
console.error = oldConsoleError;
return result;
};
I chose Symbol as the less expected type.
And called it:
const propsInfo = getPropsInfo(Hello);
console.log(propsInfo);
As result I got: {boo: "string", foo: "number"}
P.S.: I have not tested this on other types. Just for fun! :)