io-ts-human-reporter
Customizable and smart io-ts error reporting.
Have you ever got yourself into position that you wanted to present io-ts validation
errors to actual end users?
Or perhaps, your types are quite complex and error messages are not really helpful even during development?
Or maybe you are just looking for a customizable way to display missing or invalid fields on API request payloads?
If the answer for any of the above questions is yes - I think I got you covered.
goal
Provide human-friendly error messages based on io-ts validation. So human friendly, that you could even show them to anyone having basic idea about json.
usage/examples
npm i io-ts-human-reporter
# fp-ts and io-ts are package peerDependencies
# so make sure you have these also installed
import * as t from 'io-ts';
import { report, reportOne } from 'io-ts-humman-reporter';
const codec = t.type({
root: t.type({
a: t.number,
b: t.string,
c: t.union([
t.type({ c1: t.string, c2: t.string }),
t.type({ d1: t.string, d2: t.string }),
]),
}),
});
const validation = codec.decode({ root: { a: 1, b: '', c: { d1: 1 } } });
report(validation);
// [
// "got '1' expected 'string' at 'root.c.d1'",
// "missing property 'd2' at 'root.c'",
// ]
reportOne(validation);
// "got '1' expected 'string' at 'root.c.d1'"
features
-
errors will be reported only from the variant which has the most in common with the given input
const codec = t.union([t.type({ a: t.number, b: t.null }), t.type({ c: t.string, d: t.number })]);
const data = { c: null };
report(codec.decode(data));
// [
// "got `null` expected 'string' at 'c'",
// "missing property 'd' at ''",
// ]
-
e.g. for translations
const codec = t.type({ a: t.number, b: t.null });
const data = { a: '11' };
report(codec.decode(data), {
messages: {
missing: (keys, path) =>
`YOINKS! You forgot to add "${keys.join(',')}" at "${path.join('/')}".`,
},
});
// [
// "got `11` expected 'number' at 'a'",
// 'YOINKS! You forgot to add "b" at "."'
// ]
-
for greater efficiency on huge objects
const codec = t.type({ a: t.number, b: t.null });
reportOne(codec.decode({ a: '11' }));
// "got `11` expected 'number' at 'a'"
reportOne(codec.decode({ a: 11, b: null }));
// null
const codec = t.type({ a: t.number, b: t.null }, 'FooBar');
const data = null;
report(codec.decode(data));
// [
// "got `null` expected 'FooBar' at ''"
// ]