The loveable React.PropTypes interface, modified for general use. The Error messages generated
// node or browser
const PropTypes = require('prop-types')
Built-in types
Simple: bool
, string
, number
, array
, object
, func
Complex:
-
oneOf(['enum1', 'enum2')
: Value must strictly equal (===
) one of these enumerated values. Addingnull
orundefined
to the list will make the value optional. -
oneOfType([PropTypes.*, ...])
: At least one validator must succeed -
objectOf(PropTypes.*)
: Every value in the obect should be the same type -
arrayOf(PropTypes.*)
: Every element in the array should be the same type -
shape({...})
: An object taking on a particular shape. If all props are optional, then the object itself is optional. The returned validator, unlike any other builtin, only requires two argumentsvalidate(val, displayName)
.
bool
,oneOf
,shape
: do not directly support.isRequired
Example usage (basic)
const validate = PropTypes.shape({
foo: PropTypes.number.isRequired,
bar: PropTypes.arrayOf(PropTypes.string),
baz: PropTypes.oneOf(['green', 'red', 'blue'])
})
let err = validate({
foo: 29,
bar: ['x', 'y', 7],
baz: 'green'
}, 'MyDisplayName')
console.log(err.toString())
// TypeError: MyDisplayName: ".baz[2]" is number, expected string
Custom types
Remeber, these type definitions are all just functions so you can write your own too! Use PropTypes.optional(fn)
to wrap your base fn with a null/undefined check and expose the original fn as .isRequired
/**
* @param {any} val
* @param {string} displayName
* @param {string} key Optional with PropTypes.shape validator
* @param {object} props Optional with PropTypes.shape validator
* @return {Error|null}
* @example customChecker(val, displayName, key, props)
* note: Checkers should have very shallow call-stacks
* Avoid using things like Array.forEach() here
*/
const myLuckyNumber = PropTypes.optional(function (val, displayName, key, props) {
if (val !== 7) return new TypeError(`${displayName}: ${key} is not 7`)
})
const validate = PropTypes.shape({
foo: myLuckyNumber.isRequired,
bar: PropTypes.arrayOf(myLuckyNumber)
})
Example usage (validate background worker params)
Add parameter validation to job handlers for something like [node-resque][] or [arquebus][] where JSON.parse() is used to generate input. This pattern could also apply to querystring parameters when writing a REST API, or untrusted input when building a dynamic SQL statement.
/**
* Define a background job similar to how React Components are defined
* @param {string} displayName
* @param {object} propTypes
* @param {function} perform(props, done)
* @return {function}
*/
function createJob(opt) {
const validate = PropTypes.shape(opt.propTypes)
return function validateAndRun(props, done) {
let err = validate(props, opt.displayName, 'props')
if (err) done(err)
else opt.perform(props, done)
}
}
const calsync = createJob({
displayName: 'CalendarSync',
propTypes: {
uid: PropTypes.string.isRequired,
fromDate: PropTypes.number.isRequired,
private: PropTypes.bool
},
perform(props, done) {
console.log(props)
done()
}
}
// Register the job handler with node-resque or arquebus
// Or just run it directly for the sake of a short example
calsync({
uid: '010101010101',
private: true
}, function (err) {
if (err) console.log(err.stack)
else console.log('done!')
})
// TypeError: CalendarSync "props.fromDate" is required