Add ability to override `isRequired`
dkreft opened this issue · 6 comments
When passing props from one component to another, I like to have a single source of truth for my propTypes--the component that actually uses the prop:
// File: A.jsx
import PropTypes from 'prop-types'
import B from './B'
export default function A({ className, foo }) {
return (
<div className={ className }>
<B foo={ foo } />
</div>
)
}
A.propTypes = {
className: PropTypes.string,
foo: B.propTypes.foo,
}
// File: B.jsx
import PropTypes from 'prop-types'
export default function B({ foo }) {
return ( /* blah blah blah */ )
}
B.propTypes = {
foo: PropTypes.string.isRequired,
}
In this case, the foo
property on A
is mandatory...which is great. Well, that is until I want to make foo
optional on A
because I'm declaring a default value for it:
A.propTypes = {
className: PropTypes.string,
// Warnings ensue...
foo: B.propTypes.foo,
}
A.defaultProps = {
foo: 'default value provided by A',
}
What I'd like to be able to do is override the isRequired
flag, perhaps like this:
A.propTypes = {
className: PropTypes.string,
foo: B.propTypes.foo.optional, // <=== `optional` overrides `isRequired`
}
If there's some other reasonable way around this problem, I'm all ears.
If foo
is required for B
, then it's absolutely required for A
in your example. In other words, omitting it on A will be a bug when it gets to B and isn't present, so it should be required for both.
Do you have another example?
@ljharb, I think you may have missed A.defaultProps
in the third code block:
In that case, it is optional for A
by virtue of the defaultProps
, but of course, prop-types
still recognizes it as a mandatory property in A
because there's no way to override the isRequired
...which is the issue that I'm seeking to resolve.
I could still pass foo
as null
and it would break, because it should, in fact, be required on A.
I feel like maybe we're speaking past each other.
I'm trying to figure out a way to make the param mandatory for B
but optional for A
, but it sounds like you're talking about the status quo.
If you have a recommendation for how to achieve this, I'm all ears.
This is how:
A.propTypes = {
foo: B.propTypes.foo, // required
};
A.defaultProps = {
foo: 'some default'
};
This way, foo
is required, but because it is also defaulted, the user doesn't have to pass it - but if they pass null
it's invalid, which is correct.