Skip to content

Instantly share code, notes, and snippets.

@tusbar
Created August 25, 2020 15:36
Show Gist options
  • Save tusbar/e0c911e304676af8d1bc7248ee5f943e to your computer and use it in GitHub Desktop.
Save tusbar/e0c911e304676af8d1bc7248ee5f943e to your computer and use it in GitHub Desktop.
import {checkPropTypes} from 'prop-types'
export function eitherRequired(propTypes) {
const names = Object.keys(propTypes)
const entries = Object.entries(propTypes)
const eitherOrType = type => (props, propName, componentName) => {
const used = names.filter(name => name in props)
if (used.length === 0) {
throw new Error(`One of the following properties is required in ${componentName}: ${names.join(', ')}`)
}
if (used.length > 1) {
throw new Error(`Only one of the following properties can be specified in ${componentName}: ${used.join(', ')}`)
}
if (type) {
return checkPropTypes({
[propName]: type
}, props, propName, componentName)
}
return null
}
return Object.fromEntries(
entries.map(([name, type]) => [
name,
eitherOrType(type)
])
)
}
// Usage
MyComponent.propTypes = {
...eitherRequired({
foo: PropTypes.string,
bar: PropTypes.exact({
id: PropTypes.string.isRequired
})
}),
baz: PropTypes.string.isRequired
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment