Skip to content

add an intersection version of PropType.oneOfType called PropType.allOfType #3974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/isomorphic/classic/types/ReactPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ var ReactPropTypes = {
node: createNodeChecker(),
objectOf: createObjectOfTypeChecker,
oneOf: createEnumTypeChecker,
allOfType: createIntersectionTypeChecker,
oneOfType: createUnionTypeChecker,
shape: createShapeTypeChecker
};
Expand Down Expand Up @@ -256,6 +257,28 @@ function createObjectOfTypeChecker(typeChecker) {
return createChainableTypeChecker(validate);
}

function createIntersectionTypeChecker(arrayOfTypeCheckers) {
if (!Array.isArray(arrayOfTypeCheckers)) {
return createChainableTypeChecker(function() {
return new Error(
`Invalid argument supplied to allOfType, expected an instance of array.`
);
});
}

function validate(props, propName, componentName, location, propFullName) {
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
var error = checker(props, propName, componentName, location, propFullName);
if (error instanceof Error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}

function createUnionTypeChecker(arrayOfTypeCheckers) {
if (!Array.isArray(arrayOfTypeCheckers)) {
return createChainableTypeChecker(function() {
Expand Down
76 changes: 76 additions & 0 deletions src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,82 @@ describe('ReactPropTypes', function() {
});
});

describe('Intersection Types', function() {
it("should fail for invalid argument", function() {
typeCheckFail(
PropTypes.allOfType(PropTypes.string, PropTypes.number),
'red',
'Invalid argument supplied to allOfType, expected an instance of array.'
);
});

it('should warn if none of the types are valid', function() {
typeCheckFail(
PropTypes.allOfType([PropTypes.string, PropTypes.number]),
[],
'Invalid prop `testProp` of type `array` supplied to `testComponent`, expected `string`.'
);

typeCheckFail(
PropTypes.allOfType([PropTypes.number, PropTypes.string]),
[],
'Invalid prop `testProp` of type `array` supplied to `testComponent`, expected `number`.'
);

var checker = PropTypes.allOfType([
PropTypes.shape({a: PropTypes.number.isRequired}),
PropTypes.shape({b: PropTypes.number.isRequired})
]);
typeCheckFail(
checker,
{a: 1},
'Required prop `testProp.b` was not specified in `testComponent`.'
);
typeCheckFail(
checker,
{b: 1},
'Required prop `testProp.a` was not specified in `testComponent`.'
);
});

it('should not warn if all of the types are valid', function() {
var checker = PropTypes.allOfType([
PropTypes.number,
PropTypes.number
]);
typeCheckPass(checker, null);
typeCheckPass(checker, 123);

checker = PropTypes.allOfType([
PropTypes.shape({a: PropTypes.number.isRequired}),
PropTypes.shape({b: PropTypes.number.isRequired})
]);
typeCheckPass(checker, {a: 1, b: 1});
});

it("should be implicitly optional and not warn without values", function() {
typeCheckPass(
PropTypes.allOfType([PropTypes.string, PropTypes.string]), null
);
typeCheckPass(
PropTypes.allOfType([PropTypes.string, PropTypes.string]), undefined
);
});

it("should warn for missing required values", function() {
typeCheckFail(
PropTypes.allOfType([PropTypes.string, PropTypes.string]).isRequired,
null,
requiredMessage
);
typeCheckFail(
PropTypes.allOfType([PropTypes.string, PropTypes.string]).isRequired,
undefined,
requiredMessage
);
});
});

describe('Union Types', function() {
it("should fail for invalid argument", function() {
typeCheckFail(
Expand Down