Composition
ziflex opened this issue · 3 comments
ziflex commented
Hi guys, thanks for this amazing library!
I wonder if there is a way how to extend predicates or compose a new one using a set of others.
Here is a use case:
interface User {
id: string;
email: string;
}
const assertUser = ow.create('User', ow.object.partialShape({
id: ow.string.nonEmpty,
email: ow.string.nonEmpty,
}))
interface Person extends User {
firstName: string;
lastName: string;
}
const assertPerson = ow.create('Person', ow.object.partialShape({
id: ow.string.nonEmpty,
email: ow.string.nonEmpty,
firstName: ow.string.nonEmpty,
lastName: ow.string.nonEmpty,
}))
I would love to be able to avoid code duplication.
sindresorhus commented
It might be possible, but it's not an easy task, especially because of TypeScript.
sindresorhus commented
I think the easiest path for reuse is this:
interface User {
id: string;
email: string;
}
const owUser = {
id: ow.string.nonEmpty,
email: ow.string.nonEmpty,
};
const assertUser = ow.create('User', ow.object.partialShape(owUser))
interface Person extends User {
firstName: string;
lastName: string;
}
const assertPerson = ow.create('Person', ow.object.partialShape({
...owUser,
firstName: ow.string.nonEmpty,
lastName: ow.string.nonEmpty,
}))
ziflex commented
That's what I ended up doing, but it's rather hacky and breaks an abstraction.
The easiest way of supporting this is to add a method something like ow.compose(name: string, ...validation: ReusableValidator<any>[])
.
But it creates 2 problems:
- TypeScript unfriendliness
- Error messages will point to different objects