mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Added createClass and PropTypes getters (w/ depreaction warnings) to React
This commit is contained in:
+4
-2
@@ -43,7 +43,6 @@
|
|||||||
"coffee-script": "^1.8.0",
|
"coffee-script": "^1.8.0",
|
||||||
"core-js": "^2.2.1",
|
"core-js": "^2.2.1",
|
||||||
"coveralls": "^2.11.6",
|
"coveralls": "^2.11.6",
|
||||||
"create-react-class": "^15.5.0",
|
|
||||||
"del": "^2.0.2",
|
"del": "^2.0.2",
|
||||||
"derequire": "^2.0.3",
|
"derequire": "^2.0.3",
|
||||||
"escape-string-regexp": "^1.0.5",
|
"escape-string-regexp": "^1.0.5",
|
||||||
@@ -73,7 +72,6 @@
|
|||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"platform": "^1.1.0",
|
"platform": "^1.1.0",
|
||||||
"prettier": "^0.22.0",
|
"prettier": "^0.22.0",
|
||||||
"prop-types": "^15.5.6",
|
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"rollup": "^0.41.6",
|
"rollup": "^0.41.6",
|
||||||
"rollup-plugin-alias": "^1.2.1",
|
"rollup-plugin-alias": "^1.2.1",
|
||||||
@@ -95,6 +93,10 @@
|
|||||||
"node": "4.x || 5.x || 6.x || 7.x",
|
"node": "4.x || 5.x || 6.x || 7.x",
|
||||||
"npm": "2.x || 3.x || 4.x"
|
"npm": "2.x || 3.x || 4.x"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"create-react-class": "^15.5.2",
|
||||||
|
"prop-types": "^15.5.6"
|
||||||
|
},
|
||||||
"commonerConfig": {
|
"commonerConfig": {
|
||||||
"version": 7
|
"version": 7
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,7 +45,12 @@ const bundles = [
|
|||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
},
|
},
|
||||||
entry: 'src/isomorphic/React.js',
|
entry: 'src/isomorphic/React.js',
|
||||||
externals: [],
|
externals: [
|
||||||
|
'create-react-class/factory',
|
||||||
|
'prop-types',
|
||||||
|
'prop-types/checkPropTypes',
|
||||||
|
'prop-types/factory',
|
||||||
|
],
|
||||||
fbEntry: 'src/fb/ReactFBEntry.js',
|
fbEntry: 'src/fb/ReactFBEntry.js',
|
||||||
hasteName: 'React',
|
hasteName: 'React',
|
||||||
isRenderer: false,
|
isRenderer: false,
|
||||||
|
|||||||
+13
-13
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"branch": null,
|
"branch": "prop-types",
|
||||||
"bundleSizes": {
|
"bundleSizes": {
|
||||||
"react.development.js (UMD_DEV)": {
|
"react.development.js (UMD_DEV)": {
|
||||||
"size": 92740,
|
"size": 76661,
|
||||||
"gzip": 23440
|
"gzip": 19565
|
||||||
},
|
},
|
||||||
"react.production.min.js (UMD_PROD)": {
|
"react.production.min.js (UMD_PROD)": {
|
||||||
"size": 10409,
|
"size": 10467,
|
||||||
"gzip": 4091
|
"gzip": 4074
|
||||||
},
|
},
|
||||||
"react-dom.development.js (UMD_DEV)": {
|
"react-dom.development.js (UMD_DEV)": {
|
||||||
"size": 563910,
|
"size": 563910,
|
||||||
@@ -34,20 +34,20 @@
|
|||||||
"gzip": 28991
|
"gzip": 28991
|
||||||
},
|
},
|
||||||
"react.development.js (NODE_DEV)": {
|
"react.development.js (NODE_DEV)": {
|
||||||
"size": 85810,
|
"size": 69636,
|
||||||
"gzip": 21432
|
"gzip": 17533
|
||||||
},
|
},
|
||||||
"react.production.min.js (NODE_PROD)": {
|
"react.production.min.js (NODE_PROD)": {
|
||||||
"size": 9288,
|
"size": 9226,
|
||||||
"gzip": 3659
|
"gzip": 3623
|
||||||
},
|
},
|
||||||
"React-dev.js (FB_DEV)": {
|
"React-dev.js (FB_DEV)": {
|
||||||
"size": 87652,
|
"size": 71493,
|
||||||
"gzip": 22071
|
"gzip": 18168
|
||||||
},
|
},
|
||||||
"React-prod.js (FB_PROD)": {
|
"React-prod.js (FB_PROD)": {
|
||||||
"size": 37663,
|
"size": 36701,
|
||||||
"gzip": 9519
|
"gzip": 9254
|
||||||
},
|
},
|
||||||
"ReactDOMStack-dev.js (FB_DEV)": {
|
"ReactDOMStack-dev.js (FB_DEV)": {
|
||||||
"size": 522667,
|
"size": 522667,
|
||||||
|
|||||||
+18
-2
@@ -20,6 +20,7 @@ var ReactVersion = require('ReactVersion');
|
|||||||
|
|
||||||
var onlyChild = require('onlyChild');
|
var onlyChild = require('onlyChild');
|
||||||
var checkPropTypes = require('checkPropTypes');
|
var checkPropTypes = require('checkPropTypes');
|
||||||
|
var createReactClass = require('createClass');
|
||||||
|
|
||||||
var createElement = ReactElement.createElement;
|
var createElement = ReactElement.createElement;
|
||||||
var createFactory = ReactElement.createFactory;
|
var createFactory = ReactElement.createFactory;
|
||||||
@@ -28,6 +29,7 @@ var cloneElement = ReactElement.cloneElement;
|
|||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
var warning = require('fbjs/lib/warning');
|
var warning = require('fbjs/lib/warning');
|
||||||
var canDefineProperty = require('canDefineProperty');
|
var canDefineProperty = require('canDefineProperty');
|
||||||
|
var didWarnPropTypesDeprecated = false;
|
||||||
var ReactElementValidator = require('ReactElementValidator');
|
var ReactElementValidator = require('ReactElementValidator');
|
||||||
createElement = ReactElementValidator.createElement;
|
createElement = ReactElementValidator.createElement;
|
||||||
createFactory = ReactElementValidator.createFactory;
|
createFactory = ReactElementValidator.createFactory;
|
||||||
@@ -60,7 +62,8 @@ var React = {
|
|||||||
|
|
||||||
// Classic
|
// Classic
|
||||||
|
|
||||||
PropTypes: ReactPropTypes,
|
PropTypes: ReactPropTypes, // TODO (bvaughn) Remove this getter in 16.0.0-alpha.10
|
||||||
|
createClass: createReactClass, // TODO (bvaughn) Remove this getter in 16.0.0-alpha.10
|
||||||
createFactory: createFactory,
|
createFactory: createFactory,
|
||||||
createMixin: createMixin,
|
createMixin: createMixin,
|
||||||
|
|
||||||
@@ -95,6 +98,7 @@ if (__DEV__) {
|
|||||||
return mixin;
|
return mixin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO (bvaughn) Remove both of these deprecation warnings in 16.0.0-alpha.10
|
||||||
if (canDefineProperty) {
|
if (canDefineProperty) {
|
||||||
Object.defineProperty(React, 'createClass', {
|
Object.defineProperty(React, 'createClass', {
|
||||||
get: function() {
|
get: function() {
|
||||||
@@ -106,7 +110,19 @@ if (__DEV__) {
|
|||||||
'drop-in replacement.',
|
'drop-in replacement.',
|
||||||
);
|
);
|
||||||
warnedForCreateClass = true;
|
warnedForCreateClass = true;
|
||||||
return undefined;
|
return createReactClass;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(React, 'PropTypes', {
|
||||||
|
get() {
|
||||||
|
warning(
|
||||||
|
didWarnPropTypesDeprecated,
|
||||||
|
'PropTypes have moved out of the react package. ' +
|
||||||
|
'Use the prop-types package from npm instead.',
|
||||||
|
);
|
||||||
|
didWarnPropTypesDeprecated = true;
|
||||||
|
return ReactPropTypes;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe('React', () => {
|
|||||||
spyOn(console, 'error');
|
spyOn(console, 'error');
|
||||||
let createClass = React.createClass;
|
let createClass = React.createClass;
|
||||||
createClass = React.createClass;
|
createClass = React.createClass;
|
||||||
expect(createClass).toBe(undefined);
|
expect(createClass).not.toBe(undefined);
|
||||||
expectDev(console.error.calls.count()).toBe(1);
|
expectDev(console.error.calls.count()).toBe(1);
|
||||||
expectDev(console.error.calls.argsFor(0)[0]).toContain(
|
expectDev(console.error.calls.argsFor(0)[0]).toContain(
|
||||||
'React.createClass is no longer supported. Use a plain ' +
|
'React.createClass is no longer supported. Use a plain ' +
|
||||||
@@ -41,4 +41,16 @@ describe('React', () => {
|
|||||||
'drop-in replacement.',
|
'drop-in replacement.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should warn once when attempting to access React.PropTypes', () => {
|
||||||
|
spyOn(console, 'error');
|
||||||
|
let PropTypes = React.PropTypes;
|
||||||
|
PropTypes = React.PropTypes;
|
||||||
|
expect(PropTypes).not.toBe(undefined);
|
||||||
|
expectDev(console.error.calls.count()).toBe(1);
|
||||||
|
expectDev(console.error.calls.argsFor(0)[0]).toContain(
|
||||||
|
'PropTypes have moved out of the react package. ' +
|
||||||
|
'Use the prop-types package from npm instead.',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @providesModule createClass
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var {Component} = require('ReactBaseClasses');
|
||||||
|
var {isValidElement} = require('ReactElement');
|
||||||
|
var ReactNoopUpdateQueue = require('ReactNoopUpdateQueue');
|
||||||
|
var factory = require('create-react-class/factory');
|
||||||
|
|
||||||
|
module.exports = factory(Component, isValidElement, ReactNoopUpdateQueue);
|
||||||
@@ -11,548 +11,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var ReactElement = require('ReactElement');
|
var {isValidElement} = require('ReactElement');
|
||||||
var ReactPropTypesSecret = require('ReactPropTypesSecret');
|
var factory = require('prop-types/factory');
|
||||||
|
|
||||||
var emptyFunction = require('fbjs/lib/emptyFunction');
|
module.exports = factory(isValidElement);
|
||||||
var getIteratorFn = require('getIteratorFn');
|
|
||||||
var invariant = require('fbjs/lib/invariant');
|
|
||||||
var warning = require('fbjs/lib/warning');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of methods that allow declaration and validation of props that are
|
|
||||||
* supplied to React components. Example usage:
|
|
||||||
*
|
|
||||||
* var Props = require('ReactPropTypes');
|
|
||||||
* var MyArticle = React.createClass({
|
|
||||||
* propTypes: {
|
|
||||||
* // An optional string prop named "description".
|
|
||||||
* description: Props.string,
|
|
||||||
*
|
|
||||||
* // A required enum prop named "category".
|
|
||||||
* category: Props.oneOf(['News','Photos']).isRequired,
|
|
||||||
*
|
|
||||||
* // A prop named "dialog" that requires an instance of Dialog.
|
|
||||||
* dialog: Props.instanceOf(Dialog).isRequired
|
|
||||||
* },
|
|
||||||
* render: function() { ... }
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* A more formal specification of how these methods are used:
|
|
||||||
*
|
|
||||||
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
|
|
||||||
* decl := ReactPropTypes.{type}(.isRequired)?
|
|
||||||
*
|
|
||||||
* Each and every declaration produces a function with the same signature. This
|
|
||||||
* allows the creation of custom validation functions. For example:
|
|
||||||
*
|
|
||||||
* var MyLink = React.createClass({
|
|
||||||
* propTypes: {
|
|
||||||
* // An optional string or URI prop named "href".
|
|
||||||
* href: function(props, propName, componentName) {
|
|
||||||
* var propValue = props[propName];
|
|
||||||
* if (propValue != null && typeof propValue !== 'string' &&
|
|
||||||
* !(propValue instanceof URI)) {
|
|
||||||
* return new Error(
|
|
||||||
* 'Expected a string or an URI for ' + propName + ' in ' +
|
|
||||||
* componentName
|
|
||||||
* );
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* },
|
|
||||||
* render: function() {...}
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
|
|
||||||
var ANONYMOUS = '<<anonymous>>';
|
|
||||||
|
|
||||||
var ReactPropTypes;
|
|
||||||
|
|
||||||
if (__DEV__) {
|
|
||||||
// Keep in sync with production version below
|
|
||||||
ReactPropTypes = {
|
|
||||||
array: createPrimitiveTypeChecker('array'),
|
|
||||||
bool: createPrimitiveTypeChecker('boolean'),
|
|
||||||
func: createPrimitiveTypeChecker('function'),
|
|
||||||
number: createPrimitiveTypeChecker('number'),
|
|
||||||
object: createPrimitiveTypeChecker('object'),
|
|
||||||
string: createPrimitiveTypeChecker('string'),
|
|
||||||
symbol: createPrimitiveTypeChecker('symbol'),
|
|
||||||
|
|
||||||
any: createAnyTypeChecker(),
|
|
||||||
arrayOf: createArrayOfTypeChecker,
|
|
||||||
element: createElementTypeChecker(),
|
|
||||||
instanceOf: createInstanceTypeChecker,
|
|
||||||
node: createNodeChecker(),
|
|
||||||
objectOf: createObjectOfTypeChecker,
|
|
||||||
oneOf: createEnumTypeChecker,
|
|
||||||
oneOfType: createUnionTypeChecker,
|
|
||||||
shape: createShapeTypeChecker,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
var productionTypeChecker = function() {
|
|
||||||
invariant(
|
|
||||||
false,
|
|
||||||
'React.PropTypes type checking code is stripped in production.',
|
|
||||||
);
|
|
||||||
};
|
|
||||||
productionTypeChecker.isRequired = productionTypeChecker;
|
|
||||||
var getProductionTypeChecker = () => productionTypeChecker;
|
|
||||||
// Keep in sync with development version above
|
|
||||||
ReactPropTypes = {
|
|
||||||
array: productionTypeChecker,
|
|
||||||
bool: productionTypeChecker,
|
|
||||||
func: productionTypeChecker,
|
|
||||||
number: productionTypeChecker,
|
|
||||||
object: productionTypeChecker,
|
|
||||||
string: productionTypeChecker,
|
|
||||||
symbol: productionTypeChecker,
|
|
||||||
|
|
||||||
any: productionTypeChecker,
|
|
||||||
arrayOf: getProductionTypeChecker,
|
|
||||||
element: productionTypeChecker,
|
|
||||||
instanceOf: getProductionTypeChecker,
|
|
||||||
node: productionTypeChecker,
|
|
||||||
objectOf: getProductionTypeChecker,
|
|
||||||
oneOf: getProductionTypeChecker,
|
|
||||||
oneOfType: getProductionTypeChecker,
|
|
||||||
shape: getProductionTypeChecker,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
|
||||||
*/
|
|
||||||
/*eslint-disable no-self-compare*/
|
|
||||||
function is(x, y) {
|
|
||||||
// SameValue algorithm
|
|
||||||
if (x === y) {
|
|
||||||
// Steps 1-5, 7-10
|
|
||||||
// Steps 6.b-6.e: +0 != -0
|
|
||||||
return x !== 0 || 1 / x === 1 / y;
|
|
||||||
} else {
|
|
||||||
// Step 6.a: NaN == NaN
|
|
||||||
return x !== x && y !== y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*eslint-enable no-self-compare*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We use an Error-like object for backward compatibility as people may call
|
|
||||||
* PropTypes directly and inspect their output. However, we don't use real
|
|
||||||
* Errors anymore. We don't inspect their stack anyway, and creating them
|
|
||||||
* is prohibitively expensive if they are created too often, such as what
|
|
||||||
* happens in oneOfType() for any type before the one that matched.
|
|
||||||
*/
|
|
||||||
function PropTypeError(message) {
|
|
||||||
this.message = message;
|
|
||||||
this.stack = '';
|
|
||||||
}
|
|
||||||
// Make `instanceof Error` still work for returned errors.
|
|
||||||
PropTypeError.prototype = Error.prototype;
|
|
||||||
|
|
||||||
function createChainableTypeChecker(validate) {
|
|
||||||
if (__DEV__) {
|
|
||||||
var manualPropTypeCallCache = {};
|
|
||||||
}
|
|
||||||
function checkType(
|
|
||||||
isRequired,
|
|
||||||
props,
|
|
||||||
propName,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
propFullName,
|
|
||||||
secret,
|
|
||||||
) {
|
|
||||||
componentName = componentName || ANONYMOUS;
|
|
||||||
propFullName = propFullName || propName;
|
|
||||||
if (__DEV__) {
|
|
||||||
if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') {
|
|
||||||
var cacheKey = `${componentName}:${propName}`;
|
|
||||||
if (!manualPropTypeCallCache[cacheKey]) {
|
|
||||||
warning(
|
|
||||||
false,
|
|
||||||
'You are manually calling a React.PropTypes validation ' +
|
|
||||||
'function for the `%s` prop on `%s`. This is deprecated ' +
|
|
||||||
'and will not work in production with the next major version. ' +
|
|
||||||
'You may be seeing this warning due to a third-party PropTypes ' +
|
|
||||||
'library. See https://fb.me/react-warning-dont-call-proptypes ' +
|
|
||||||
'for details.',
|
|
||||||
propFullName,
|
|
||||||
componentName,
|
|
||||||
);
|
|
||||||
manualPropTypeCallCache[cacheKey] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (props[propName] == null) {
|
|
||||||
if (isRequired) {
|
|
||||||
if (props[propName] === null) {
|
|
||||||
return new PropTypeError(
|
|
||||||
`The ${location} \`${propFullName}\` is marked as required ` +
|
|
||||||
`in \`${componentName}\`, but its value is \`null\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new PropTypeError(
|
|
||||||
`The ${location} \`${propFullName}\` is marked as required in ` +
|
|
||||||
`\`${componentName}\`, but its value is \`undefined\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return validate(props, propName, componentName, location, propFullName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var chainedCheckType = checkType.bind(null, false);
|
|
||||||
chainedCheckType.isRequired = checkType.bind(null, true);
|
|
||||||
|
|
||||||
return chainedCheckType;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPrimitiveTypeChecker(expectedType) {
|
|
||||||
function validate(
|
|
||||||
props,
|
|
||||||
propName,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
propFullName,
|
|
||||||
secret,
|
|
||||||
) {
|
|
||||||
var propValue = props[propName];
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
if (propType !== expectedType) {
|
|
||||||
// `propValue` being instance of, say, date/regexp, pass the 'object'
|
|
||||||
// check, but we can offer a more precise error message here rather than
|
|
||||||
// 'of type `object`'.
|
|
||||||
var preciseType = getPreciseType(propValue);
|
|
||||||
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type ` +
|
|
||||||
`\`${preciseType}\` supplied to \`${componentName}\`, expected ` +
|
|
||||||
`\`${expectedType}\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAnyTypeChecker() {
|
|
||||||
return createChainableTypeChecker(emptyFunction.thatReturnsNull);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createArrayOfTypeChecker(typeChecker) {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
if (typeof typeChecker !== 'function') {
|
|
||||||
return new PropTypeError(
|
|
||||||
`Property \`${propFullName}\` of component \`${componentName}\` has invalid PropType notation inside arrayOf.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
var propValue = props[propName];
|
|
||||||
if (!Array.isArray(propValue)) {
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type ` +
|
|
||||||
`\`${propType}\` supplied to \`${componentName}\`, expected an array.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < propValue.length; i++) {
|
|
||||||
var error = typeChecker(
|
|
||||||
propValue,
|
|
||||||
i,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
`${propFullName}[${i}]`,
|
|
||||||
ReactPropTypesSecret,
|
|
||||||
);
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createElementTypeChecker() {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
var propValue = props[propName];
|
|
||||||
if (!ReactElement.isValidElement(propValue)) {
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type ` +
|
|
||||||
`\`${propType}\` supplied to \`${componentName}\`, expected a single ReactElement.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createInstanceTypeChecker(expectedClass) {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
if (!(props[propName] instanceof expectedClass)) {
|
|
||||||
var expectedClassName = expectedClass.name || ANONYMOUS;
|
|
||||||
var actualClassName = getClassName(props[propName]);
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type ` +
|
|
||||||
`\`${actualClassName}\` supplied to \`${componentName}\`, expected ` +
|
|
||||||
`instance of \`${expectedClassName}\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createEnumTypeChecker(expectedValues) {
|
|
||||||
if (!Array.isArray(expectedValues)) {
|
|
||||||
warning(
|
|
||||||
false,
|
|
||||||
'Invalid argument supplied to oneOf, expected an instance of array.',
|
|
||||||
);
|
|
||||||
return emptyFunction.thatReturnsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
var propValue = props[propName];
|
|
||||||
for (var i = 0; i < expectedValues.length; i++) {
|
|
||||||
if (is(propValue, expectedValues[i])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var valuesString = JSON.stringify(expectedValues);
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of value \`${propValue}\` ` +
|
|
||||||
`supplied to \`${componentName}\`, expected one of ${valuesString}.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createObjectOfTypeChecker(typeChecker) {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
if (typeof typeChecker !== 'function') {
|
|
||||||
return new PropTypeError(
|
|
||||||
`Property \`${propFullName}\` of component \`${componentName}\` has invalid PropType notation inside objectOf.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
var propValue = props[propName];
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
if (propType !== 'object') {
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type ` +
|
|
||||||
`\`${propType}\` supplied to \`${componentName}\`, expected an object.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (var key in propValue) {
|
|
||||||
if (propValue.hasOwnProperty(key)) {
|
|
||||||
var error = typeChecker(
|
|
||||||
propValue,
|
|
||||||
key,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
`${propFullName}.${key}`,
|
|
||||||
ReactPropTypesSecret,
|
|
||||||
);
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createUnionTypeChecker(arrayOfTypeCheckers) {
|
|
||||||
if (!Array.isArray(arrayOfTypeCheckers)) {
|
|
||||||
warning(
|
|
||||||
false,
|
|
||||||
'Invalid argument supplied to oneOfType, expected an instance of array.',
|
|
||||||
);
|
|
||||||
return emptyFunction.thatReturnsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
|
|
||||||
var checker = arrayOfTypeCheckers[i];
|
|
||||||
if (
|
|
||||||
checker(
|
|
||||||
props,
|
|
||||||
propName,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
propFullName,
|
|
||||||
ReactPropTypesSecret,
|
|
||||||
) == null
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` supplied to ` +
|
|
||||||
`\`${componentName}\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNodeChecker() {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
if (!isNode(props[propName])) {
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` supplied to ` +
|
|
||||||
`\`${componentName}\`, expected a ReactNode.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createShapeTypeChecker(shapeTypes) {
|
|
||||||
function validate(props, propName, componentName, location, propFullName) {
|
|
||||||
var propValue = props[propName];
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
if (propType !== 'object') {
|
|
||||||
return new PropTypeError(
|
|
||||||
`Invalid ${location} \`${propFullName}\` of type \`${propType}\` ` +
|
|
||||||
`supplied to \`${componentName}\`, expected \`object\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (var key in shapeTypes) {
|
|
||||||
var checker = shapeTypes[key];
|
|
||||||
if (!checker) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var error = checker(
|
|
||||||
propValue,
|
|
||||||
key,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
`${propFullName}.${key}`,
|
|
||||||
ReactPropTypesSecret,
|
|
||||||
);
|
|
||||||
if (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return createChainableTypeChecker(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isNode(propValue) {
|
|
||||||
switch (typeof propValue) {
|
|
||||||
case 'number':
|
|
||||||
case 'string':
|
|
||||||
case 'undefined':
|
|
||||||
return true;
|
|
||||||
case 'boolean':
|
|
||||||
return !propValue;
|
|
||||||
case 'object':
|
|
||||||
if (Array.isArray(propValue)) {
|
|
||||||
return propValue.every(isNode);
|
|
||||||
}
|
|
||||||
if (propValue === null || ReactElement.isValidElement(propValue)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var iteratorFn = getIteratorFn(propValue);
|
|
||||||
if (iteratorFn) {
|
|
||||||
var iterator = iteratorFn.call(propValue);
|
|
||||||
var step;
|
|
||||||
if (iteratorFn !== propValue.entries) {
|
|
||||||
while (!(step = iterator.next()).done) {
|
|
||||||
if (!isNode(step.value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Iterator will provide entry [k,v] tuples rather than values.
|
|
||||||
while (!(step = iterator.next()).done) {
|
|
||||||
var entry = step.value;
|
|
||||||
if (entry) {
|
|
||||||
if (!isNode(entry[1])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSymbol(propType, propValue) {
|
|
||||||
// Native Symbol.
|
|
||||||
if (propType === 'symbol') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
|
|
||||||
if (propValue['@@toStringTag'] === 'Symbol') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback for non-spec compliant Symbols which are polyfilled.
|
|
||||||
if (typeof Symbol === 'function' && propValue instanceof Symbol) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equivalent of `typeof` but with special handling for array and regexp.
|
|
||||||
function getPropType(propValue) {
|
|
||||||
var propType = typeof propValue;
|
|
||||||
if (Array.isArray(propValue)) {
|
|
||||||
return 'array';
|
|
||||||
}
|
|
||||||
if (propValue instanceof RegExp) {
|
|
||||||
// Old webkits (at least until Android 4.0) return 'function' rather than
|
|
||||||
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/
|
|
||||||
// passes PropTypes.object.
|
|
||||||
return 'object';
|
|
||||||
}
|
|
||||||
if (isSymbol(propType, propValue)) {
|
|
||||||
return 'symbol';
|
|
||||||
}
|
|
||||||
return propType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This handles more types than `getPropType`. Only used for error messages.
|
|
||||||
// See `createPrimitiveTypeChecker`.
|
|
||||||
function getPreciseType(propValue) {
|
|
||||||
var propType = getPropType(propValue);
|
|
||||||
if (propType === 'object') {
|
|
||||||
if (propValue instanceof Date) {
|
|
||||||
return 'date';
|
|
||||||
} else if (propValue instanceof RegExp) {
|
|
||||||
return 'regexp';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return propType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns class name of the object, if any.
|
|
||||||
function getClassName(propValue) {
|
|
||||||
if (!propValue.constructor || !propValue.constructor.name) {
|
|
||||||
return ANONYMOUS;
|
|
||||||
}
|
|
||||||
return propValue.constructor.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = ReactPropTypes;
|
|
||||||
|
|||||||
@@ -1,219 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013-present, Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*
|
|
||||||
* @emails react-core
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
describe('ReactPropTypesProduction', function() {
|
|
||||||
var PropTypes;
|
|
||||||
var React;
|
|
||||||
var ReactTestUtils;
|
|
||||||
var oldProcess;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
__DEV__ = false;
|
|
||||||
|
|
||||||
// Mutating process.env.NODE_ENV would cause our babel plugins to do the
|
|
||||||
// wrong thing. If you change this, make sure to test with jest --no-cache.
|
|
||||||
oldProcess = process;
|
|
||||||
global.process = {
|
|
||||||
...process,
|
|
||||||
env: {...process.env, NODE_ENV: 'production'},
|
|
||||||
};
|
|
||||||
|
|
||||||
jest.resetModules();
|
|
||||||
PropTypes = require('ReactPropTypes');
|
|
||||||
React = require('react');
|
|
||||||
ReactTestUtils = require('ReactTestUtils');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
__DEV__ = true;
|
|
||||||
global.process = oldProcess;
|
|
||||||
});
|
|
||||||
|
|
||||||
function expectThrowsInProduction(declaration, value) {
|
|
||||||
var props = {testProp: value};
|
|
||||||
expect(() => {
|
|
||||||
declaration(props, 'testProp', 'testComponent', 'prop');
|
|
||||||
}).toThrowError('Minified React error #144');
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Primitive Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.array, /please/);
|
|
||||||
expectThrowsInProduction(PropTypes.array.isRequired, /please/);
|
|
||||||
expectThrowsInProduction(PropTypes.array.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.array.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.bool, []);
|
|
||||||
expectThrowsInProduction(PropTypes.bool.isRequired, []);
|
|
||||||
expectThrowsInProduction(PropTypes.bool.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.bool.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.func, false);
|
|
||||||
expectThrowsInProduction(PropTypes.func.isRequired, false);
|
|
||||||
expectThrowsInProduction(PropTypes.func.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.func.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.number, function() {});
|
|
||||||
expectThrowsInProduction(PropTypes.number.isRequired, function() {});
|
|
||||||
expectThrowsInProduction(PropTypes.number.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.number.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.string, 0);
|
|
||||||
expectThrowsInProduction(PropTypes.string.isRequired, 0);
|
|
||||||
expectThrowsInProduction(PropTypes.string.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.string.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.symbol, 0);
|
|
||||||
expectThrowsInProduction(PropTypes.symbol.isRequired, 0);
|
|
||||||
expectThrowsInProduction(PropTypes.symbol.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.symbol.isRequired, undefined);
|
|
||||||
expectThrowsInProduction(PropTypes.object, '');
|
|
||||||
expectThrowsInProduction(PropTypes.object.isRequired, '');
|
|
||||||
expectThrowsInProduction(PropTypes.object.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.object.isRequired, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Any Type', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.any, null);
|
|
||||||
expectThrowsInProduction(PropTypes.any.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.any.isRequired, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ArrayOf Type', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.arrayOf({foo: PropTypes.string}), {
|
|
||||||
foo: 'bar',
|
|
||||||
});
|
|
||||||
expectThrowsInProduction(PropTypes.arrayOf(PropTypes.number), [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
'b',
|
|
||||||
]);
|
|
||||||
expectThrowsInProduction(PropTypes.arrayOf(PropTypes.number), {
|
|
||||||
'0': 'maybe-array',
|
|
||||||
length: 1,
|
|
||||||
});
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Component Type', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.element, [<div />, <div />]);
|
|
||||||
expectThrowsInProduction(PropTypes.element, 123);
|
|
||||||
expectThrowsInProduction(PropTypes.element, 'foo');
|
|
||||||
expectThrowsInProduction(PropTypes.element, false);
|
|
||||||
expectThrowsInProduction(PropTypes.element.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.element.isRequired, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Instance Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.instanceOf(Date), {});
|
|
||||||
expectThrowsInProduction(PropTypes.instanceOf(Date).isRequired, {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('React Component Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.node, {});
|
|
||||||
expectThrowsInProduction(PropTypes.node.isRequired, null);
|
|
||||||
expectThrowsInProduction(PropTypes.node.isRequired, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ObjectOf Type', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.objectOf({foo: PropTypes.string}), {
|
|
||||||
foo: 'bar',
|
|
||||||
});
|
|
||||||
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
c: 'b',
|
|
||||||
});
|
|
||||||
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), [1, 2]);
|
|
||||||
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), null);
|
|
||||||
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('OneOf Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.oneOf('red', 'blue'), 'red');
|
|
||||||
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), true);
|
|
||||||
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), null);
|
|
||||||
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Union Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.oneOfType(PropTypes.string, PropTypes.number),
|
|
||||||
'red',
|
|
||||||
);
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Shape Types', function() {
|
|
||||||
it('should be a no-op', function() {
|
|
||||||
expectThrowsInProduction(PropTypes.shape({}), 'some string');
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.shape({key: PropTypes.number}).isRequired,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
expectThrowsInProduction(
|
|
||||||
PropTypes.shape({key: PropTypes.number}).isRequired,
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Custom validator', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
jest.resetModules();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not have been called', function() {
|
|
||||||
var spy = jest.fn();
|
|
||||||
function Component() {
|
|
||||||
return <div />;
|
|
||||||
}
|
|
||||||
Component.propTypes = {num: spy};
|
|
||||||
|
|
||||||
var instance = <Component num={5} />;
|
|
||||||
ReactTestUtils.renderIntoDocument(instance);
|
|
||||||
|
|
||||||
expect(spy).not.toBeCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -11,84 +11,4 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var ReactPropTypesSecret = require('ReactPropTypesSecret');
|
module.exports = require('prop-types/checkPropTypes');
|
||||||
|
|
||||||
var invariant = require('fbjs/lib/invariant');
|
|
||||||
var warning = require('fbjs/lib/warning');
|
|
||||||
|
|
||||||
var loggedTypeFailures = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert that the values match with the type specs.
|
|
||||||
* Error messages are memorized and will only be shown once.
|
|
||||||
*
|
|
||||||
* @param {object} typeSpecs Map of name to a ReactPropType
|
|
||||||
* @param {object} values Runtime values that need to be type-checked
|
|
||||||
* @param {string} location e.g. "prop", "context", "child context"
|
|
||||||
* @param {string} componentName Name of the component for error messages.
|
|
||||||
* @param {?Function} getStack Returns the component stack.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
|
|
||||||
if (__DEV__) {
|
|
||||||
for (var typeSpecName in typeSpecs) {
|
|
||||||
if (typeSpecs.hasOwnProperty(typeSpecName)) {
|
|
||||||
var error;
|
|
||||||
// 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.
|
|
||||||
invariant(
|
|
||||||
typeof typeSpecs[typeSpecName] === 'function',
|
|
||||||
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
|
|
||||||
'React.PropTypes.',
|
|
||||||
componentName || 'React class',
|
|
||||||
location,
|
|
||||||
typeSpecName,
|
|
||||||
);
|
|
||||||
error = typeSpecs[typeSpecName](
|
|
||||||
values,
|
|
||||||
typeSpecName,
|
|
||||||
componentName,
|
|
||||||
location,
|
|
||||||
null,
|
|
||||||
ReactPropTypesSecret,
|
|
||||||
);
|
|
||||||
} catch (ex) {
|
|
||||||
error = ex;
|
|
||||||
}
|
|
||||||
warning(
|
|
||||||
!error || error instanceof 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,
|
|
||||||
);
|
|
||||||
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
|
|
||||||
// Only monitor this failure once because there tends to be a lot of the
|
|
||||||
// same error.
|
|
||||||
loggedTypeFailures[error.message] = true;
|
|
||||||
|
|
||||||
var stack = getStack ? getStack() : '';
|
|
||||||
|
|
||||||
warning(
|
|
||||||
false,
|
|
||||||
'Failed %s type: %s%s',
|
|
||||||
location,
|
|
||||||
error.message,
|
|
||||||
stack != null ? stack : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = checkPropTypes;
|
|
||||||
|
|||||||
@@ -1438,11 +1438,12 @@ create-hmac@^1.1.0, create-hmac@^1.1.2:
|
|||||||
create-hash "^1.1.0"
|
create-hash "^1.1.0"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
|
|
||||||
create-react-class@^15.5.0:
|
create-react-class@^15.5.2:
|
||||||
version "15.5.0"
|
version "15.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.5.0.tgz#7508ffcad56a0804fb244d6ff70b07648abfe5fb"
|
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.5.2.tgz#6a8758348df660b88326a0e764d569f274aad681"
|
||||||
dependencies:
|
dependencies:
|
||||||
fbjs "^0.8.9"
|
fbjs "^0.8.9"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
cross-spawn-async@^2.2.2:
|
cross-spawn-async@^2.2.2:
|
||||||
version "2.2.5"
|
version "2.2.5"
|
||||||
|
|||||||
Reference in New Issue
Block a user