diff --git a/src/isomorphic/classic/types/ReactPropTypes.js b/src/isomorphic/classic/types/ReactPropTypes.js index 250531f2e7..9400cd76fa 100644 --- a/src/isomorphic/classic/types/ReactPropTypes.js +++ b/src/isomorphic/classic/types/ReactPropTypes.js @@ -190,9 +190,11 @@ function createInstanceTypeChecker(expectedClass) { if (!(props[propName] instanceof expectedClass)) { var locationName = ReactPropTypeLocationNames[location]; var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); return new Error( - `Invalid ${locationName} \`${propFullName}\` supplied to ` + - `\`${componentName}\`, expected instance of \`${expectedClassName}\`.` + `Invalid ${locationName} \`${propFullName}\` of type ` + + `\`${actualClassName}\` supplied to \`${componentName}\`, expected ` + + `instance of \`${expectedClassName}\`.` ); } return null; @@ -412,4 +414,12 @@ function getPreciseType(propValue) { return propType; } +// Returns class name of the object, if any. +function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return '<>'; + } + return propValue.constructor.name; +} + module.exports = ReactPropTypes; diff --git a/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js b/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js index 412d0f2e69..95ca5cac45 100644 --- a/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js +++ b/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js @@ -161,8 +161,8 @@ describe('ReactPropTypes', function() { typeCheckFail( PropTypes.arrayOf(PropTypes.number), [1, 2, 'b'], - 'Invalid prop `testProp[2]` of type `string` supplied to `testComponent`, ' + - 'expected `number`.' + 'Invalid prop `testProp[2]` of type `string` supplied to ' + + '`testComponent`, expected `number`.' ); }); @@ -173,8 +173,8 @@ describe('ReactPropTypes', function() { typeCheckFail( PropTypes.arrayOf(PropTypes.instanceOf(Thing)), [new Thing(), 'xyz'], - 'Invalid prop `testProp[1]` supplied to `testComponent`, expected instance of `' + - name + '`.' + 'Invalid prop `testProp[1]` of type `String` supplied to ' + + '`testComponent`, expected instance of `' + name + '`.' ); }); @@ -277,6 +277,7 @@ describe('ReactPropTypes', function() { describe('Instance Types', function() { it('should warn for invalid instances', function() { function Person() {} + function Cat() {} var personName = Person.name || '<>'; var dateName = Date.name || '<>'; var regExpName = RegExp.name || '<>'; @@ -284,32 +285,44 @@ describe('ReactPropTypes', function() { typeCheckFail( PropTypes.instanceOf(Person), false, - 'Invalid prop `testProp` supplied to `testComponent`, expected ' + - 'instance of `' + personName + '`.' + 'Invalid prop `testProp` of type `Boolean` supplied to ' + + '`testComponent`, expected instance of `' + personName + '`.' ); typeCheckFail( PropTypes.instanceOf(Person), {}, - 'Invalid prop `testProp` supplied to `testComponent`, expected ' + - 'instance of `' + personName + '`.' + 'Invalid prop `testProp` of type `Object` supplied to ' + + '`testComponent`, expected instance of `' + personName + '`.' ); typeCheckFail( PropTypes.instanceOf(Person), '', - 'Invalid prop `testProp` supplied to `testComponent`, expected ' + - 'instance of `' + personName + '`.' + 'Invalid prop `testProp` of type `String` supplied to ' + + '`testComponent`, expected instance of `' + personName + '`.' ); typeCheckFail( PropTypes.instanceOf(Date), {}, - 'Invalid prop `testProp` supplied to `testComponent`, expected ' + - 'instance of `' + dateName + '`.' + 'Invalid prop `testProp` of type `Object` supplied to ' + + '`testComponent`, expected instance of `' + dateName + '`.' ); typeCheckFail( PropTypes.instanceOf(RegExp), {}, - 'Invalid prop `testProp` supplied to `testComponent`, expected ' + - 'instance of `' + regExpName + '`.' + 'Invalid prop `testProp` of type `Object` supplied to ' + + '`testComponent`, expected instance of `' + regExpName + '`.' + ); + typeCheckFail( + PropTypes.instanceOf(Person), + new Cat(), + 'Invalid prop `testProp` of type `Cat` supplied to ' + + '`testComponent`, expected instance of `' + personName + '`.' + ); + typeCheckFail( + PropTypes.instanceOf(Person), + Object.create(null), + 'Invalid prop `testProp` of type `<>` supplied to ' + + '`testComponent`, expected instance of `' + personName + '`.' ); }); @@ -503,8 +516,8 @@ describe('ReactPropTypes', function() { typeCheckFail( PropTypes.objectOf(PropTypes.instanceOf(Thing)), {a: new Thing(), b: 'xyz'}, - 'Invalid prop `testProp.b` supplied to `testComponent`, expected instance of `' + - name + '`.' + 'Invalid prop `testProp.b` of type `String` supplied to ' + + '`testComponent`, expected instance of `' + name + '`.' ); });