Combine validators
Validators are extensively used when dealing with user inputs and data from external sources.
In many cases, you need more than one validator for a given input. In that case, you need to combine multiple validator functions into a single validator.
The easiest case is when each validator gets a string to validate, and outputs a boolean (its signature is (string) => boolean
).
For example, the following two functions validate different aspects of numbers:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function isPositive(n) {
return parseInt(n) > 0;
}
console.log(isNumeric("5")); // true
console.log(isNumeric("abc")); // false
console.log(isNumeric("5g")); // false
console.log(isNumeric("0")); // true
console.log(isPositive("0")); // false
console.log(isPositive("abc")); // false
console.log(isPositive("5g")); // true
To make a function that validates that a given string is both a number and is positive, use a combine
function that outputs true
if all the passed validators return true
:
const combine = (...fns) => (val) => fns.reduce((memo, fn) => memo && fn(val), true);
And to use it:
const combined = combine(isNumeric, isPositive);
console.log(combined("5")); // true
console.log(combined("0")); // false
console.log(combined("5g")); // false
The combined validator's signature is the same (string) => boolean
, making higher-order validators possible:
function lessThan5(n) {
return parseInt(n) < 5;
}
const evenMoreCombined = combine(combined, lessThan5);
console.log(evenMoreCombined("4")); // true
console.log(evenMoreCombined("6")); // false
This way you can create arbitrarily complex validators out of simple ones.