Skip to content

Commit

Permalink
Remove JSX propTypes validation (#28328)
Browse files Browse the repository at this point in the history
This removes the remaining `propTypes` validation calls, making
declaring `propTypes` a no-op. In other words, React itself will no
longer validate the `propTypes` that you declare on your components.

In general, our recommendation is to use static type checking (e.g.
TypeScript). If you'd like to still run propTypes checks, you can do so
manually, same as you'd do outside React:

```js
import checkPropTypes from 'prop-types/checkPropTypes';

function Button(props) {
  checkPropTypes(Button.propTypes, prop, 'prop', Button.name)
  // ...
}
```

This could be automated as a Babel plugin if you want to keep these
checks implicit. (We will not be providing such a plugin, but someone in
community might be interested in building or maintaining one.)

DiffTrain build for [353ecd0](353ecd0)
  • Loading branch information
gaearon committed Feb 21, 2024
1 parent 6b820da commit d319f43
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 896 deletions.
172 changes: 0 additions & 172 deletions compiled/facebook-www/JSXDEVRuntime-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -807,111 +807,6 @@ if (__DEV__) {
return "";
}

var loggedTypeFailures = {};
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;

function setCurrentlyValidatingElement$1(element) {
{
if (element) {
var owner = element._owner;
var stack = describeUnknownElementTypeFrameInDEV(
element.type,
owner ? owner.type : null
);
ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
} else {
ReactDebugCurrentFrame$1.setExtraStackFrame(null);
}
}
}

function checkPropTypes(
typeSpecs,
values,
location,
componentName,
element
) {
{
// $FlowFixMe[incompatible-use] This is okay but Flow doesn't know it.
var has = Function.call.bind(hasOwnProperty);

for (var typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.

try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
if (typeof typeSpecs[typeSpecName] !== "function") {
// eslint-disable-next-line react-internal/prod-error-codes
var err = Error(
(componentName || "React class") +
": " +
location +
" type `" +
typeSpecName +
"` is invalid; " +
"it must be a function, usually from the `prop-types` package, but received `" +
typeof typeSpecs[typeSpecName] +
"`." +
"This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."
);
err.name = "Invariant Violation";
throw err;
}

error$1 = typeSpecs[typeSpecName](
values,
typeSpecName,
componentName,
location,
null,
"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"
);
} catch (ex) {
error$1 = ex;
}

if (error$1 && !(error$1 instanceof Error)) {
setCurrentlyValidatingElement$1(element);

error(
"%s: type specification of %s" +
" `%s` is invalid; the type checker " +
"function must return `null` or an `Error` but returned a %s. " +
"You may have forgotten to pass an argument to the type checker " +
"creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " +
"shape all require an argument).",
componentName || "React class",
location,
typeSpecName,
typeof error$1
);

setCurrentlyValidatingElement$1(null);
}

if (
error$1 instanceof Error &&
!(error$1.message in loggedTypeFailures)
) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error$1.message] = true;
setCurrentlyValidatingElement$1(element);

error("Failed %s type: %s", location, error$1.message);

setCurrentlyValidatingElement$1(null);
}
}
}
}
}

var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
Expand Down Expand Up @@ -1314,8 +1209,6 @@ if (__DEV__) {

if (type === REACT_FRAGMENT_TYPE) {
validateFragmentProps(element);
} else {
validatePropTypes(element);
}

return element;
Expand Down Expand Up @@ -1542,71 +1435,6 @@ if (__DEV__) {
}
}

var propTypesMisspellWarningShown = false;
/**
* Given an element, validate that its props follow the propTypes definition,
* provided by the type.
*
* @param {ReactElement} element
*/

function validatePropTypes(element) {
{
var type = element.type;

if (type === null || type === undefined || typeof type === "string") {
return;
}

if (type.$$typeof === REACT_CLIENT_REFERENCE) {
return;
}

var propTypes;

if (typeof type === "function") {
propTypes = type.propTypes;
} else if (
typeof type === "object" &&
(type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
// Inner props are checked in the reconciler.
type.$$typeof === REACT_MEMO_TYPE)
) {
propTypes = type.propTypes;
} else {
return;
}

if (propTypes) {
// Intentionally inside to avoid triggering lazy initializers:
var name = getComponentNameFromType(type);
checkPropTypes(propTypes, element.props, "prop", name, element);
} else if (
type.PropTypes !== undefined &&
!propTypesMisspellWarningShown
) {
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:

var _name = getComponentNameFromType(type);

error(
"Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",
_name || "Unknown"
);
}

if (
typeof type.getDefaultProps === "function" &&
!type.getDefaultProps.isReactClassApproved
) {
error(
"getDefaultProps is only used on classic React.createClass " +
"definitions. Use a static property named `defaultProps` instead."
);
}
}
}

var jsxDEV = jsxDEV$1;

exports.Fragment = REACT_FRAGMENT_TYPE;
Expand Down
172 changes: 0 additions & 172 deletions compiled/facebook-www/JSXDEVRuntime-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -807,111 +807,6 @@ if (__DEV__) {
return "";
}

var loggedTypeFailures = {};
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;

function setCurrentlyValidatingElement$1(element) {
{
if (element) {
var owner = element._owner;
var stack = describeUnknownElementTypeFrameInDEV(
element.type,
owner ? owner.type : null
);
ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
} else {
ReactDebugCurrentFrame$1.setExtraStackFrame(null);
}
}
}

function checkPropTypes(
typeSpecs,
values,
location,
componentName,
element
) {
{
// $FlowFixMe[incompatible-use] This is okay but Flow doesn't know it.
var has = Function.call.bind(hasOwnProperty);

for (var typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.

try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
if (typeof typeSpecs[typeSpecName] !== "function") {
// eslint-disable-next-line react-internal/prod-error-codes
var err = Error(
(componentName || "React class") +
": " +
location +
" type `" +
typeSpecName +
"` is invalid; " +
"it must be a function, usually from the `prop-types` package, but received `" +
typeof typeSpecs[typeSpecName] +
"`." +
"This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."
);
err.name = "Invariant Violation";
throw err;
}

error$1 = typeSpecs[typeSpecName](
values,
typeSpecName,
componentName,
location,
null,
"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"
);
} catch (ex) {
error$1 = ex;
}

if (error$1 && !(error$1 instanceof Error)) {
setCurrentlyValidatingElement$1(element);

error(
"%s: type specification of %s" +
" `%s` is invalid; the type checker " +
"function must return `null` or an `Error` but returned a %s. " +
"You may have forgotten to pass an argument to the type checker " +
"creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " +
"shape all require an argument).",
componentName || "React class",
location,
typeSpecName,
typeof error$1
);

setCurrentlyValidatingElement$1(null);
}

if (
error$1 instanceof Error &&
!(error$1.message in loggedTypeFailures)
) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error$1.message] = true;
setCurrentlyValidatingElement$1(element);

error("Failed %s type: %s", location, error$1.message);

setCurrentlyValidatingElement$1(null);
}
}
}
}
}

var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
Expand Down Expand Up @@ -1314,8 +1209,6 @@ if (__DEV__) {

if (type === REACT_FRAGMENT_TYPE) {
validateFragmentProps(element);
} else {
validatePropTypes(element);
}

return element;
Expand Down Expand Up @@ -1542,71 +1435,6 @@ if (__DEV__) {
}
}

var propTypesMisspellWarningShown = false;
/**
* Given an element, validate that its props follow the propTypes definition,
* provided by the type.
*
* @param {ReactElement} element
*/

function validatePropTypes(element) {
{
var type = element.type;

if (type === null || type === undefined || typeof type === "string") {
return;
}

if (type.$$typeof === REACT_CLIENT_REFERENCE) {
return;
}

var propTypes;

if (typeof type === "function") {
propTypes = type.propTypes;
} else if (
typeof type === "object" &&
(type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
// Inner props are checked in the reconciler.
type.$$typeof === REACT_MEMO_TYPE)
) {
propTypes = type.propTypes;
} else {
return;
}

if (propTypes) {
// Intentionally inside to avoid triggering lazy initializers:
var name = getComponentNameFromType(type);
checkPropTypes(propTypes, element.props, "prop", name, element);
} else if (
type.PropTypes !== undefined &&
!propTypesMisspellWarningShown
) {
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:

var _name = getComponentNameFromType(type);

error(
"Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",
_name || "Unknown"
);
}

if (
typeof type.getDefaultProps === "function" &&
!type.getDefaultProps.isReactClassApproved
) {
error(
"getDefaultProps is only used on classic React.createClass " +
"definitions. Use a static property named `defaultProps` instead."
);
}
}
}

var jsxDEV = jsxDEV$1;

exports.Fragment = REACT_FRAGMENT_TYPE;
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4ea424e63d1a74ce57ef675b64a8c4eabfdb2fdc
353ecd05160a318a3f75260ee7906fd12e05cb9d
Loading

0 comments on commit d319f43

Please sign in to comment.