Validating your inputs is important, even when the sender is an API- in the land of JSON-based data exchange, we can't guarantee which keys exist without checking.
Philipp's team uses the "Runtypes" library to solve this problem. It lets them write code like this:
r.Array(r.Record({ id: r.Number, name: r.String })).check(inputData)
This verifies that inputData
is an array of objects with id
fields (containing numbers), and a name
field (containing strings).
For more complex validation, Runtypes lets you use add constraint functions to your types. So, for example, if you wanted to ensure a number is in the range of 0-52, you could do:
const YearIndexes = r.Number.withConstraint((n) => n >= 0 && n <= 52);
You could do that. But Phillip's co-worker wanted to find a more declarative approach that doesn't have any of those pesky function calls in it.
const YearIndexes = Union(
Literal('0'),
Literal('1'),
Literal('2'),
Literal('3'),
Literal('4'),
Literal('5'),
Literal('6'),
Literal('7'),
Literal('8'),
Literal('9'),
Literal('10'),
Literal('11'),
Literal('12'),
Literal('13'),
Literal('14'),
Literal('15'),
Literal('16'),
Literal('17'),
Literal('18'),
Literal('19'),
Literal('20'),
Literal('21'),
Literal('22'),
Literal('23'),
Literal('24'),
Literal('25'),
Literal('26'),
Literal('27'),
Literal('28'),
Literal('29'),
Literal('30'),
Literal('31'),
Literal('32'),
Literal('33'),
Literal('34'),
Literal('35'),
Literal('36'),
Literal('37'),
Literal('38'),
Literal('39'),
Literal('40'),
Literal('41'),
Literal('42'),
Literal('43'),
Literal('44'),
Literal('45'),
Literal('46'),
Literal('47'),
Literal('48'),
Literal('49'),
Literal('50'),
Literal('51'),
Literal('52'),
// this is the maximal amount of years prospect can be insured for in the range 18-70 years.
);