Closed 414owen closed 5 years ago
Based on the two forms you want, I'd expect this (which is very close to what you have):
PropTypes.oneOfType([
PropTypes.shape({
type: PropTypes.oneOf(['haskeller']).isRequired,
data: PropTypes.shape({
favoriteMonad: PropTypes.string.isRequired,
}).isRequired,
}),
PropTypes.shape({
type: PropTypes.oneOf(['javascripter']).isRequired,
data: PropTypes.shape({
favoriteLoop: PropTypes.string.isRequired,
favoriteLibrary: PropTypes.string.isRequired,
}).isRequired,
}),
])
If you had the two shapes defined separately, it becomes much more readable:
const haskeller = PropTypes.shape({
type: PropTypes.oneOf(['haskeller']).isRequired,
data: PropTypes.shape({
favoriteMonad: PropTypes.string.isRequired,
}).isRequired,
});
const javascripter = PropTypes.shape({
type: PropTypes.oneOf(['javascripter']).isRequired,
data: PropTypes.shape({
favoriteLoop: PropTypes.string.isRequired,
favoriteLibrary: PropTypes.string.isRequired,
}).isRequired,
});
…
PropTypes.oneOfType([haskeller, javascripter])
Thanks @ljharb. It might be nice to have something similar in the docs, I find it hard to imagine it's an uncommon use case.
A PR to improve the docs is always welcome!
Algebraic data types, or tagged unions, represent a choice of multiple shapes.
Say I have an algebraic datatype which can take one of two forms:
Where
type
is the discriminant.At the moment, I'm validating this using:
So several things here:
PropTypes.oneOf(['haskell'])
becomesPropTypes.is('haskell')