Skip to content

Instantly share code, notes, and snippets.

@brianmcallister
Created March 30, 2016 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianmcallister/fd0e4ec1947fcb860b19b81d7fbfbf83 to your computer and use it in GitHub Desktop.
Save brianmcallister/fd0e4ec1947fcb860b19b81d7fbfbf83 to your computer and use it in GitHub Desktop.
Override React's `isRequired` prop type validation. Allows you to express "If not X, than A, B, C".
// Override the `isRequired` validation of a list of props for another, single
// prop. For example, if you had a number of props used to generate a URL path,
// you could require all of them *unless* a full path was passed as a prop.
//
// @param {array} toOverride - Array of strings to 'override', or ignore.
// @param {function} [type] - PropType validation function. Optional.
// @param {boolean} [required] - Validate the prop as required. Optional.
//
// @returns {function} Callback function for custom prop validation.
// See the `customProp` in http://bit.ly/1nhwVQ3.
export default function overridePropValidation(toOverride, type, required) {
return (props, name, component, location) => {
// If the prop wasn't passed, validate all other keys were.
if (!props[name]) {
// If not, throw an error.
if (!hasAllKeys(props, toOverride)) {
return new Error(
`${component} requires either a ${name} prop, or the following
attributes as props: (${toOverride.join(', ')}).`
);
}
return null;
}
if (!type) {
return null;
}
if (required) {
return type.isRequired(props, name, component, location);
}
return type(props, name, component, location);
};
}
// Check if a `list` has all `keys`.
//
// @param {object|array} list - List of keys, or array.
// @param {array} keys - Array of keys to check exist in `list`.
//
// @returns {boolean} `true` if all keys exist, `false` if they don't.
const hasAllKeys = (list, keys) => {
// Assume if `list` isn't an array, it's an object.
if (toString.call(list) !== '[object Array]') {
list = Object.keys(list);
}
for (let key of keys) {
if (list.indexOf(key) === -1) {
return false;
}
}
return true;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment