mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Extract ReactPropTypes to separate module
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# prop-types
|
||||
|
||||
Runtime type checking for React props and similar objects.
|
||||
|
||||
Refer to the [React documentation](https://facebook.github.io/react/docs/typechecking-with-proptypes.html) for more information.
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
|
||||
|
||||
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 (process.env.NODE_ENV !== 'production') {
|
||||
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;
|
||||
}
|
||||
process.env.NODE_ENV !== 'production' ? 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) : void 0;
|
||||
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() : '';
|
||||
|
||||
process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '') : void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = checkPropTypes;
|
||||
@@ -0,0 +1,484 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var emptyFunction = require('fbjs/lib/emptyFunction');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
|
||||
var checkPropTypes = require('./checkPropTypes');
|
||||
|
||||
module.exports = function (isValidElement) {
|
||||
/* global Symbol */
|
||||
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
|
||||
|
||||
/**
|
||||
* Returns the iterator method function contained on the iterable object.
|
||||
*
|
||||
* Be sure to invoke the function with the iterable as context:
|
||||
*
|
||||
* var iteratorFn = getIteratorFn(myIterable);
|
||||
* if (iteratorFn) {
|
||||
* var iterator = iteratorFn.call(myIterable);
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* @param {?object} maybeIterable
|
||||
* @return {?function}
|
||||
*/
|
||||
function getIteratorFn(maybeIterable) {
|
||||
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
|
||||
if (typeof iteratorFn === 'function') {
|
||||
return iteratorFn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (process.env.NODE_ENV !== 'production') {
|
||||
// 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 = function () {
|
||||
return 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 (process.env.NODE_ENV !== 'production') {
|
||||
var manualPropTypeCallCache = {};
|
||||
}
|
||||
function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
|
||||
componentName = componentName || ANONYMOUS;
|
||||
propFullName = propFullName || propName;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') {
|
||||
var cacheKey = componentName + ':' + propName;
|
||||
if (!manualPropTypeCallCache[cacheKey]) {
|
||||
process.env.NODE_ENV !== 'production' ? 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) : void 0;
|
||||
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 (!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)) {
|
||||
process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0;
|
||||
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)) {
|
||||
process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
|
||||
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 || 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;
|
||||
}
|
||||
|
||||
ReactPropTypes.checkPropTypes = checkPropTypes;
|
||||
ReactPropTypes.PropTypes = ReactPropTypes;
|
||||
|
||||
return ReactPropTypes;
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
var factory = require('./factory');
|
||||
|
||||
module.exports = factory(React.isValidElement);
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
|
||||
|
||||
module.exports = ReactPropTypesSecret;
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "prop-types",
|
||||
"version": "15.5.0-alpha.0",
|
||||
"description": "Runtime type checking for React props and similar objects.",
|
||||
"main": "index.js",
|
||||
"license": "BSD-3-Clause",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"PATENTS",
|
||||
"factory.js",
|
||||
"index.js",
|
||||
"checkPropTypes.js",
|
||||
"lib"
|
||||
],
|
||||
"repository": "facebook/react",
|
||||
"keywords": [
|
||||
"react"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/facebook/react/issues"
|
||||
},
|
||||
"homepage": "https://facebook.github.io/react/",
|
||||
"dependencies": {
|
||||
"fbjs": "^0.8.9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^19.0.2",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 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('prop-types', () => {
|
||||
it('index', () => {
|
||||
var PropTypes = require('./');
|
||||
var checkPropTypes = PropTypes.checkPropTypes;
|
||||
|
||||
spyOn(console, 'error');
|
||||
checkPropTypes({ foo: PropTypes.string }, { foo: '123' }, 'prop', 'Test1');
|
||||
expect(console.error.calls.count()).toBe(0);
|
||||
checkPropTypes({ foo: PropTypes.string }, { foo: 123 }, 'prop', 'Test1');
|
||||
expect(console.error.calls.count()).toBe(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).toContain(
|
||||
'Warning: Failed prop type: Invalid prop `foo` of type `number` ' +
|
||||
'supplied to `Test1`, expected `string`.'
|
||||
);
|
||||
});
|
||||
|
||||
it('factory', () => {
|
||||
var React = require('react');
|
||||
var factory = require('./factory');
|
||||
var PropTypes = factory(React.isValidElement);
|
||||
var checkPropTypes = PropTypes.checkPropTypes;
|
||||
|
||||
spyOn(console, 'error');
|
||||
checkPropTypes({ foo: PropTypes.string }, { foo: '123' }, 'prop', 'Test2');
|
||||
expect(console.error.calls.count()).toBe(0);
|
||||
checkPropTypes({ foo: PropTypes.string }, { foo: 123 }, 'prop', 'Test2');
|
||||
expect(console.error.calls.count()).toBe(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).toContain(
|
||||
'Warning: Failed prop type: Invalid prop `foo` of type `number` ' +
|
||||
'supplied to `Test2`, expected `string`.'
|
||||
);
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -39,6 +39,7 @@
|
||||
"coffee-script": "^1.8.0",
|
||||
"core-js": "^2.2.1",
|
||||
"coveralls": "^2.11.6",
|
||||
"create-react-class": "15.5.0",
|
||||
"del": "^2.0.2",
|
||||
"derequire": "^2.0.3",
|
||||
"eslint": "^3.10.2",
|
||||
@@ -69,7 +70,7 @@
|
||||
"merge-stream": "^1.0.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"platform": "^1.1.0",
|
||||
"create-react-class": "15.5.0",
|
||||
"prop-types": "15.5.0-alpha.0",
|
||||
"run-sequence": "^1.1.4",
|
||||
"through2": "^2.0.0",
|
||||
"tmp": "~0.0.28",
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
"dependencies": {
|
||||
"fbjs": "^0.8.9",
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.0"
|
||||
"object-assign": "^4.1.0",
|
||||
"prop-types": "15.5.0-alpha.0"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
|
||||
@@ -28,7 +28,9 @@ var createFactory = ReactElement.createFactory;
|
||||
var cloneElement = ReactElement.cloneElement;
|
||||
|
||||
if (__DEV__) {
|
||||
var canDefineProperty = require('canDefineProperty');
|
||||
var ReactElementValidator = require('ReactElementValidator');
|
||||
var didWarnPropTypesDeprecated = false;
|
||||
createElement = ReactElementValidator.createElement;
|
||||
createFactory = ReactElementValidator.createFactory;
|
||||
cloneElement = ReactElementValidator.cloneElement;
|
||||
@@ -90,4 +92,21 @@ var React = {
|
||||
__spread: __spread,
|
||||
};
|
||||
|
||||
// TODO: Fix tests so that this deprecation warning doesn't cause failures.
|
||||
// if (__DEV__) {
|
||||
// if (canDefineProperty) {
|
||||
// Object.defineProperty(React, 'PropTypes', {
|
||||
// get() {
|
||||
// warning(
|
||||
// didWarnPropTypesDeprecated,
|
||||
// 'Accessing PropTypes via the main React package is deprecated. Use ' +
|
||||
// 'the prop-types package from npm instead.'
|
||||
// );
|
||||
// didWarnPropTypesDeprecated = true;
|
||||
// return ReactPropTypes;
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
module.exports = React;
|
||||
|
||||
@@ -222,7 +222,7 @@ describe('ReactContextValidator', () => {
|
||||
ReactTestUtils.renderIntoDocument(<Component testContext={{bar: 123}} />);
|
||||
expect(console.error.calls.count()).toBe(1);
|
||||
expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
|
||||
'Warning: Failed childContext type: ' +
|
||||
'Warning: Failed child context type: ' +
|
||||
'The child context `foo` is marked as required in `Component`, but its ' +
|
||||
'value is `undefined`.\n' +
|
||||
' in Component (at **)'
|
||||
@@ -232,7 +232,7 @@ describe('ReactContextValidator', () => {
|
||||
|
||||
expect(console.error.calls.count()).toBe(2);
|
||||
expect(normalizeCodeLocInfo(console.error.calls.argsFor(1)[0])).toBe(
|
||||
'Warning: Failed childContext type: ' +
|
||||
'Warning: Failed child context type: ' +
|
||||
'Invalid child context `foo` of type `number` ' +
|
||||
'supplied to `Component`, expected `string`.\n' +
|
||||
' in Component (at **)'
|
||||
|
||||
@@ -11,526 +11,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames');
|
||||
var ReactPropTypesSecret = require('ReactPropTypesSecret');
|
||||
var {isValidElement} = require('ReactElement');
|
||||
var factory = require('prop-types/factory');
|
||||
|
||||
var emptyFunction = require('emptyFunction');
|
||||
var getIteratorFn = require('getIteratorFn');
|
||||
var warning = require('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 = {
|
||||
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,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
if (isRequired) {
|
||||
if (props[propName] === null) {
|
||||
return new PropTypeError(
|
||||
`The ${locationName} \`${propFullName}\` is marked as required ` +
|
||||
`in \`${componentName}\`, but its value is \`null\`.`
|
||||
);
|
||||
}
|
||||
return new PropTypeError(
|
||||
`The ${locationName} \`${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) {
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
// `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 ${locationName} \`${propFullName}\` of type ` +
|
||||
`\`${preciseType}\` supplied to \`${componentName}\`, expected ` +
|
||||
`\`${expectedType}\`.`
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return createChainableTypeChecker(validate);
|
||||
}
|
||||
|
||||
function createAnyTypeChecker() {
|
||||
return createChainableTypeChecker(emptyFunction.thatReturns(null));
|
||||
}
|
||||
|
||||
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 locationName = ReactPropTypeLocationNames[location];
|
||||
var propType = getPropType(propValue);
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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 locationName = ReactPropTypeLocationNames[location];
|
||||
var propType = getPropType(propValue);
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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 locationName = ReactPropTypeLocationNames[location];
|
||||
var expectedClassName = expectedClass.name || ANONYMOUS;
|
||||
var actualClassName = getClassName(props[propName]);
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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 locationName = ReactPropTypeLocationNames[location];
|
||||
var valuesString = JSON.stringify(expectedValues);
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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') {
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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;
|
||||
}
|
||||
}
|
||||
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${propFullName}\` supplied to ` +
|
||||
`\`${componentName}\`.`
|
||||
);
|
||||
}
|
||||
return createChainableTypeChecker(validate);
|
||||
}
|
||||
|
||||
function createNodeChecker() {
|
||||
function validate(props, propName, componentName, location, propFullName) {
|
||||
if (!isNode(props[propName])) {
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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') {
|
||||
var locationName = ReactPropTypeLocationNames[location];
|
||||
return new PropTypeError(
|
||||
`Invalid ${locationName} \`${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;
|
||||
module.exports = factory(isValidElement);
|
||||
|
||||
@@ -660,7 +660,7 @@ var ReactCompositeComponent = {
|
||||
this._checkContextTypes(
|
||||
Component.childContextTypes,
|
||||
childContext,
|
||||
'childContext'
|
||||
'child context'
|
||||
);
|
||||
}
|
||||
for (var name in childContext) {
|
||||
|
||||
@@ -4198,6 +4198,12 @@ promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@15.5.0-alpha.0:
|
||||
version "15.5.0-alpha.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.0-alpha.0.tgz#a342108678256db125eee3d1ae2f889af3531bd7"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
|
||||
prr@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
|
||||
|
||||
Reference in New Issue
Block a user