Babel plugin to typecheck React components with legacy PropTypes compatible with React 19.
Works with Function (including Arrow Function) and Class (including @decorated) components, React or Redux reducers.
Supports defining extend class name regular expression pattern with classNameMatcher
(unset by default).
Supports debugging skipped components with logIgnoredBinding
or logIgnoredClass
boolean options (enabled by default).
Input:
import PropTypes from 'prop-types';
function FunctionComponent() {}
FunctionComponent.propTypes = {};
const ArrowFunctionComponent = () => {};
ArrowFunctionComponent.propTypes = {};
class ClassComponent extends React.PureComponent {
render() {} // render method is required to validate class components
}
ClassComponent.propTypes = {};
const AnonymousFunction = function () {};
AnonymousFunction.displayName = "MyComponent";
AnonymousFunction.propTypes = {};
Output:
import _checkPropTypes from "prop-types/checkPropTypes";
import PropTypes from 'prop-types';
function FunctionComponent() {
_checkPropTypes(FunctionComponent.propTypes, arguments[0], "prop",
FunctionComponent.displayName || "FunctionComponent");
}
FunctionComponent.propTypes = {};
const ArrowFunctionComponent = _props => {
_checkPropTypes(ArrowFunctionComponent.propTypes, _props, "prop",
ArrowFunctionComponent.displayName || "ArrowFunctionComponent");
};
ArrowFunctionComponent.propTypes = {};
class ClassComponent extends React.PureComponent {
render() {
_checkPropTypes(this.constructor.propTypes, this.props, "prop",
ClassComponent.displayName || "ClassComponent");
}
}
ClassComponent.propTypes = {};
const AnonymousFunction = function () {
_checkPropTypes(AnonymousFunction.propTypes, arguments[0], "prop",
AnonymousFunction.displayName || "AnonymousFunction");
};
AnonymousFunction.displayName = "MyComponent";
AnonymousFunction.propTypes = {};
In addition you can typecheck reducers (actually first argument of everything what looks like function):
import { useReducer } from "react";
import { createStore } from "redux";
function counter(state, action) {
if (action.type === "INCREMENT") return state + 1;
if (action.type === "DECREMENT") return state - 1;
return state;
}
counter.propTypes = PropTypes.number.isRequired;
const ReactComponent = () => {
const [state, dispatch] = useReducer(counter, 0);
};
const reduxStore = createStore(counter, 0);
See tests for more examples.
Update react-is
for prop-types
with Yarn resolutions (otherwise you’ll get validation errors for PropTypes.node
or PropTypes.element
):
{
"dependencies": {
"prop-types": "^15.8.1"
},
"resolutions": {
"prop-types/react-is": "^19.0.0"
}
}
Install plugin package:
yarn add --dev babel-plugin-check-prop-types
Update Babel configuration:
export default () => {
const plugins = [];
if (process.env.NODE_ENV !== "production") { // enable plugin only for non-production bundle
plugins.push(["check-prop-types", {
// classNameMatcher: /^UI\.(.+)/,
// logIgnoredBinding: false,
// logIgnoredClass: false,
}]);
}
return { plugins };
};