Report the actual type when PropTypes.instanceOf fails
Jorrit Schippers committed
Aug 13, 2015 at 08:20 UTC
cf6222dd71792e69783e64ed0586756845c50b39
2 files changed
+41
-18
src/isomorphic/classic/types/ReactPropTypes.js
+12
-2
@@ -190,9 +190,11 @@ function createInstanceTypeChecker(expectedClass) {
190
if (!(props[propName] instanceof expectedClass)) {
191
var locationName = ReactPropTypeLocationNames[location];
192
var expectedClassName = expectedClass.name || ANONYMOUS;
193
+ var actualClassName = getClassName(props[propName]);
194
return new Error(
194
- `Invalid ${locationName} \`${propFullName}\` supplied to ` +
195
- `\`${componentName}\`, expected instance of \`${expectedClassName}\`.`
195
+ `Invalid ${locationName} \`${propFullName}\` of type ` +
196
+ `\`${actualClassName}\` supplied to \`${componentName}\`, expected ` +
197
+ `instance of \`${expectedClassName}\`.`
198
);
199
}
200
return null;
@@ -412,4 +414,12 @@ function getPreciseType(propValue) {
414
return propType;
415
}
416
417
+// Returns class name of the object, if any.
418
+function getClassName(propValue) {
419
+ if (!propValue.constructor || !propValue.constructor.name) {
420
+ return '<<anonymous>>';
421
+ }
422
+ return propValue.constructor.name;
423
+}
424
+
425
module.exports = ReactPropTypes;
src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js
+29
-16
@@ -161,8 +161,8 @@ describe('ReactPropTypes', function() {
161
typeCheckFail(
162
PropTypes.arrayOf(PropTypes.number),
163
[1, 2, 'b'],
164
- 'Invalid prop `testProp[2]` of type `string` supplied to `testComponent`, ' +
165
- 'expected `number`.'
164
+ 'Invalid prop `testProp[2]` of type `string` supplied to ' +
165
+ '`testComponent`, expected `number`.'
166
);
167
});
168
@@ -173,8 +173,8 @@ describe('ReactPropTypes', function() {
173
typeCheckFail(
174
PropTypes.arrayOf(PropTypes.instanceOf(Thing)),
175
[new Thing(), 'xyz'],
176
- 'Invalid prop `testProp[1]` supplied to `testComponent`, expected instance of `' +
177
- name + '`.'
176
+ 'Invalid prop `testProp[1]` of type `String` supplied to ' +
177
+ '`testComponent`, expected instance of `' + name + '`.'
178
);
179
});
180
@@ -277,6 +277,7 @@ describe('ReactPropTypes', function() {
277
describe('Instance Types', function() {
278
it('should warn for invalid instances', function() {
279
function Person() {}
280
+ function Cat() {}
281
var personName = Person.name || '<<anonymous>>';
282
var dateName = Date.name || '<<anonymous>>';
283
var regExpName = RegExp.name || '<<anonymous>>';
@@ -284,32 +285,44 @@ describe('ReactPropTypes', function() {
285
typeCheckFail(
286
PropTypes.instanceOf(Person),
287
false,
287
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
288
- 'instance of `' + personName + '`.'
288
+ 'Invalid prop `testProp` of type `Boolean` supplied to ' +
289
+ '`testComponent`, expected instance of `' + personName + '`.'
290
);
291
typeCheckFail(
292
PropTypes.instanceOf(Person),
293
{},
293
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
294
- 'instance of `' + personName + '`.'
294
+ 'Invalid prop `testProp` of type `Object` supplied to ' +
295
+ '`testComponent`, expected instance of `' + personName + '`.'
296
);
297
typeCheckFail(
298
PropTypes.instanceOf(Person),
299
'',
299
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
300
- 'instance of `' + personName + '`.'
300
+ 'Invalid prop `testProp` of type `String` supplied to ' +
301
+ '`testComponent`, expected instance of `' + personName + '`.'
302
);
303
typeCheckFail(
304
PropTypes.instanceOf(Date),
305
{},
305
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
306
- 'instance of `' + dateName + '`.'
306
+ 'Invalid prop `testProp` of type `Object` supplied to ' +
307
+ '`testComponent`, expected instance of `' + dateName + '`.'
308
);
309
typeCheckFail(
310
PropTypes.instanceOf(RegExp),
311
{},
311
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
312
- 'instance of `' + regExpName + '`.'
312
+ 'Invalid prop `testProp` of type `Object` supplied to ' +
313
+ '`testComponent`, expected instance of `' + regExpName + '`.'
314
+ );
315
+ typeCheckFail(
316
+ PropTypes.instanceOf(Person),
317
+ new Cat(),
318
+ 'Invalid prop `testProp` of type `Cat` supplied to ' +
319
+ '`testComponent`, expected instance of `' + personName + '`.'
320
+ );
321
+ typeCheckFail(
322
+ PropTypes.instanceOf(Person),
323
+ Object.create(null),
324
+ 'Invalid prop `testProp` of type `<<anonymous>>` supplied to ' +
325
+ '`testComponent`, expected instance of `' + personName + '`.'
326
);
327
});
328
@@ -503,8 +516,8 @@ describe('ReactPropTypes', function() {
516
typeCheckFail(
517
PropTypes.objectOf(PropTypes.instanceOf(Thing)),
518
{a: new Thing(), b: 'xyz'},
506
- 'Invalid prop `testProp.b` supplied to `testComponent`, expected instance of `' +
507
- name + '`.'
519
+ 'Invalid prop `testProp.b` of type `String` supplied to ' +
520
+ '`testComponent`, expected instance of `' + name + '`.'
521
);
522
});
523