2015-01-30 01:10:49 +00:00
|
|
|
/**
|
2015-03-23 22:07:33 +00:00
|
|
|
* Copyright (c) 2015-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.
|
2015-01-30 01:10:49 +00:00
|
|
|
*
|
|
|
|
* @providesModule createStrictShapeTypeChecker
|
2015-03-24 16:26:16 +00:00
|
|
|
* @flow
|
2015-01-30 01:10:49 +00:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2016-07-05 13:34:00 +00:00
|
|
|
var ReactPropTypeLocationNames = require('react/lib/ReactPropTypeLocationNames');
|
2016-07-21 16:01:07 +00:00
|
|
|
var ReactPropTypesSecret = require('react/lib/ReactPropTypesSecret');
|
2015-01-30 01:10:49 +00:00
|
|
|
|
2016-03-02 12:27:13 +00:00
|
|
|
var invariant = require('fbjs/lib/invariant');
|
2015-01-30 01:10:49 +00:00
|
|
|
var merge = require('merge');
|
|
|
|
|
2015-03-24 16:26:16 +00:00
|
|
|
function createStrictShapeTypeChecker(
|
|
|
|
shapeTypes: {[key: string]: ReactPropsCheckType}
|
|
|
|
): ReactPropsChainableTypeChecker {
|
|
|
|
function checkType(isRequired, props, propName, componentName, location?) {
|
2015-01-30 01:10:49 +00:00
|
|
|
if (!props[propName]) {
|
|
|
|
if (isRequired) {
|
|
|
|
invariant(
|
|
|
|
false,
|
2015-12-01 00:12:44 +00:00
|
|
|
`Required object \`${propName}\` was not specified in ` +
|
2015-01-30 01:10:49 +00:00
|
|
|
`\`${componentName}\`.`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var propValue = props[propName];
|
|
|
|
var propType = typeof propValue;
|
2015-03-24 16:26:16 +00:00
|
|
|
var locationName =
|
|
|
|
location && ReactPropTypeLocationNames[location] || '(unknown)';
|
2015-01-30 01:10:49 +00:00
|
|
|
if (propType !== 'object') {
|
|
|
|
invariant(
|
|
|
|
false,
|
|
|
|
`Invalid ${locationName} \`${propName}\` of type \`${propType}\` ` +
|
|
|
|
`supplied to \`${componentName}\`, expected \`object\`.`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// We need to check all keys in case some are required but missing from
|
|
|
|
// props.
|
|
|
|
var allKeys = merge(props[propName], shapeTypes);
|
|
|
|
for (var key in allKeys) {
|
|
|
|
var checker = shapeTypes[key];
|
2016-07-03 21:39:45 +00:00
|
|
|
if (!checker) {
|
|
|
|
invariant(
|
|
|
|
false,
|
|
|
|
`Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` +
|
|
|
|
`\nBad object: ` + JSON.stringify(props[propName], null, ' ') +
|
|
|
|
`\nValid keys: ` + JSON.stringify(Object.keys(shapeTypes), null, ' ')
|
|
|
|
);
|
|
|
|
}
|
2016-07-21 16:01:07 +00:00
|
|
|
var error = checker(propValue, key, componentName, location, null, ReactPropTypesSecret);
|
2015-01-30 01:10:49 +00:00
|
|
|
if (error) {
|
|
|
|
invariant(
|
|
|
|
false,
|
|
|
|
error.message +
|
|
|
|
`\nBad object: ` + JSON.stringify(props[propName], null, ' ')
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-03-24 16:26:16 +00:00
|
|
|
function chainedCheckType(
|
|
|
|
props: {[key: string]: any},
|
|
|
|
propName: string,
|
|
|
|
componentName: string,
|
|
|
|
location?: string
|
|
|
|
): ?Error {
|
|
|
|
return checkType(false, props, propName, componentName, location);
|
|
|
|
}
|
2015-01-30 01:10:49 +00:00
|
|
|
chainedCheckType.isRequired = checkType.bind(null, true);
|
|
|
|
return chainedCheckType;
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = createStrictShapeTypeChecker;
|