Skip to content

Commit 6893763

Browse files
committed
add an intersection version of PropType.oneOfType called PropType.allOfType
1 parent 58fb322 commit 6893763

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/isomorphic/classic/types/ReactPropTypes.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ var ReactPropTypes = {
8181
node: createNodeChecker(),
8282
objectOf: createObjectOfTypeChecker,
8383
oneOf: createEnumTypeChecker,
84+
allOfType: createIntersectionTypeChecker,
8485
oneOfType: createUnionTypeChecker,
8586
shape: createShapeTypeChecker
8687
};
@@ -256,6 +257,28 @@ function createObjectOfTypeChecker(typeChecker) {
256257
return createChainableTypeChecker(validate);
257258
}
258259

260+
function createIntersectionTypeChecker(arrayOfTypeCheckers) {
261+
if (!Array.isArray(arrayOfTypeCheckers)) {
262+
return createChainableTypeChecker(function() {
263+
return new Error(
264+
`Invalid argument supplied to allOfType, expected an instance of array.`
265+
);
266+
});
267+
}
268+
269+
function validate(props, propName, componentName, location, propFullName) {
270+
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
271+
var checker = arrayOfTypeCheckers[i];
272+
var error = checker(props, propName, componentName, location, propFullName);
273+
if (error instanceof Error) {
274+
return error;
275+
}
276+
}
277+
return null;
278+
}
279+
return createChainableTypeChecker(validate);
280+
}
281+
259282
function createUnionTypeChecker(arrayOfTypeCheckers) {
260283
if (!Array.isArray(arrayOfTypeCheckers)) {
261284
return createChainableTypeChecker(function() {

src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,82 @@ describe('ReactPropTypes', function() {
579579
});
580580
});
581581

582+
describe('Intersection Types', function() {
583+
it("should fail for invalid argument", function() {
584+
typeCheckFail(
585+
PropTypes.allOfType(PropTypes.string, PropTypes.number),
586+
'red',
587+
'Invalid argument supplied to allOfType, expected an instance of array.'
588+
);
589+
});
590+
591+
it('should warn if none of the types are valid', function() {
592+
typeCheckFail(
593+
PropTypes.allOfType([PropTypes.string, PropTypes.number]),
594+
[],
595+
'Invalid prop `testProp` of type `array` supplied to `testComponent`, expected `string`.'
596+
);
597+
598+
typeCheckFail(
599+
PropTypes.allOfType([PropTypes.number, PropTypes.string]),
600+
[],
601+
'Invalid prop `testProp` of type `array` supplied to `testComponent`, expected `number`.'
602+
);
603+
604+
var checker = PropTypes.allOfType([
605+
PropTypes.shape({a: PropTypes.number.isRequired}),
606+
PropTypes.shape({b: PropTypes.number.isRequired})
607+
]);
608+
typeCheckFail(
609+
checker,
610+
{a: 1},
611+
'Required prop `testProp.b` was not specified in `testComponent`.'
612+
);
613+
typeCheckFail(
614+
checker,
615+
{b: 1},
616+
'Required prop `testProp.a` was not specified in `testComponent`.'
617+
);
618+
});
619+
620+
it('should not warn if all of the types are valid', function() {
621+
var checker = PropTypes.allOfType([
622+
PropTypes.number,
623+
PropTypes.number
624+
]);
625+
typeCheckPass(checker, null);
626+
typeCheckPass(checker, 123);
627+
628+
checker = PropTypes.allOfType([
629+
PropTypes.shape({a: PropTypes.number.isRequired}),
630+
PropTypes.shape({b: PropTypes.number.isRequired})
631+
]);
632+
typeCheckPass(checker, {a: 1, b: 1});
633+
});
634+
635+
it("should be implicitly optional and not warn without values", function() {
636+
typeCheckPass(
637+
PropTypes.allOfType([PropTypes.string, PropTypes.string]), null
638+
);
639+
typeCheckPass(
640+
PropTypes.allOfType([PropTypes.string, PropTypes.string]), undefined
641+
);
642+
});
643+
644+
it("should warn for missing required values", function() {
645+
typeCheckFail(
646+
PropTypes.allOfType([PropTypes.string, PropTypes.string]).isRequired,
647+
null,
648+
requiredMessage
649+
);
650+
typeCheckFail(
651+
PropTypes.allOfType([PropTypes.string, PropTypes.string]).isRequired,
652+
undefined,
653+
requiredMessage
654+
);
655+
});
656+
});
657+
582658
describe('Union Types', function() {
583659
it("should fail for invalid argument", function() {
584660
typeCheckFail(

0 commit comments

Comments
 (0)