checkPropTypes.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * Copyright (c) 2013-present, Facebook, Inc.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. 'use strict';
  8. var printWarning = function() {};
  9. if (process.env.NODE_ENV !== 'production') {
  10. var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
  11. var loggedTypeFailures = {};
  12. var has = Function.call.bind(Object.prototype.hasOwnProperty);
  13. printWarning = function(text) {
  14. var message = 'Warning: ' + text;
  15. if (typeof console !== 'undefined') {
  16. console.error(message);
  17. }
  18. try {
  19. // --- Welcome to debugging React ---
  20. // This error was thrown as a convenience so that you can use this stack
  21. // to find the callsite that caused this warning to fire.
  22. throw new Error(message);
  23. } catch (x) {}
  24. };
  25. }
  26. /**
  27. * Assert that the values match with the type specs.
  28. * Error messages are memorized and will only be shown once.
  29. *
  30. * @param {object} typeSpecs Map of name to a ReactPropType
  31. * @param {object} values Runtime values that need to be type-checked
  32. * @param {string} location e.g. "prop", "context", "child context"
  33. * @param {string} componentName Name of the component for error messages.
  34. * @param {?Function} getStack Returns the component stack.
  35. * @private
  36. */
  37. function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
  38. if (process.env.NODE_ENV !== 'production') {
  39. for (var typeSpecName in typeSpecs) {
  40. if (has(typeSpecs, typeSpecName)) {
  41. var error;
  42. // Prop type validation may throw. In case they do, we don't want to
  43. // fail the render phase where it didn't fail before. So we log it.
  44. // After these have been cleaned up, we'll let them throw.
  45. try {
  46. // This is intentionally an invariant that gets caught. It's the same
  47. // behavior as without this statement except with a better message.
  48. if (typeof typeSpecs[typeSpecName] !== 'function') {
  49. var err = Error(
  50. (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
  51. 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
  52. );
  53. err.name = 'Invariant Violation';
  54. throw err;
  55. }
  56. error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
  57. } catch (ex) {
  58. error = ex;
  59. }
  60. if (error && !(error instanceof Error)) {
  61. printWarning(
  62. (componentName || 'React class') + ': type specification of ' +
  63. location + ' `' + typeSpecName + '` is invalid; the type checker ' +
  64. 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
  65. 'You may have forgotten to pass an argument to the type checker ' +
  66. 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
  67. 'shape all require an argument).'
  68. );
  69. }
  70. if (error instanceof Error && !(error.message in loggedTypeFailures)) {
  71. // Only monitor this failure once because there tends to be a lot of the
  72. // same error.
  73. loggedTypeFailures[error.message] = true;
  74. var stack = getStack ? getStack() : '';
  75. printWarning(
  76. 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
  77. );
  78. }
  79. }
  80. }
  81. }
  82. }
  83. /**
  84. * Resets warning cache when testing.
  85. *
  86. * @private
  87. */
  88. checkPropTypes.resetWarningCache = function() {
  89. if (process.env.NODE_ENV !== 'production') {
  90. loggedTypeFailures = {};
  91. }
  92. }
  93. module.exports = checkPropTypes;