Custom Rules
One of the main features of fluentvalidation-ts is that it is fully extensible, allowing you define your own custom validation logic and inject it via the .must
rule.
The documentation page for the .must
rule contains several examples that demonstrate the different ways in which you can define and consume custom rules, as well as a full API reference which outlines everything in detail.
The Gist
Custom validation logic is defined by way of a predicate function, which takes a value and returns a boolean (true/false) value indicating whether or not the value is valid.
You can pass custom validation logic directly into the .must
rule with a predicate:
this.ruleFor('numberOfSocks').must(numberOfSocks => numberOfSocks % 2 === 0);
If you want to reuse the logic, you could pull it out into a named function:
const beEven = (value: number) => value % 2 === 0;
Then you can just pass the named function into .must
, like so:
this.ruleFor('numberOfSocks').must(beEven);
The predicate function can also depend on the value of the model as well as the value of the property:
this.ruleFor('numberOfSocks').must(
(numberOfSocks, model) => numberOfSocks === 2 * model.numberOfPants
);
You can define groups of rules by forming arrays:
const beEven = (value: number) => value % 2 === 0;
const bePositive = (value: number) => value > 0;
const beEvenAndPositive = [beEven, bePositive];
These arrays can be passed directly to the .must
rule:
this.ruleFor('numberOfSocks').must(beEvenAndPositive);
You can also attach a custom message to your rule, alongside the predicate:
const beEven = {
predicate: (value: number) => value % 2 === 0,
message: 'Please enter an even number',
};
As before, you just pass this into the .must
rule directly:
this.ruleFor('numberOfSocks').must(beEven);
Again, you can use arrays to compose rules together:
const beEven = {
predicate: (value: number) => value % 2 === 0,
message: 'Please enter an even number',
};
const bePositive = {
predicate: (value: number) => value > 0,
message: 'Please enter a positive number',
};
const beEvenAndPositive = [beEven, bePositive];
You can even compose groups of rules together by spreading the arrays:
const newRuleGroup = [...ruleGroup, ...otherRuleGroup];