Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composition #233

Open
ziflex opened this issue Feb 22, 2022 · 3 comments
Open

Composition #233

ziflex opened this issue Feb 22, 2022 · 3 comments

Comments

@ziflex
Copy link

ziflex commented Feb 22, 2022

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
Copy link
Owner

It might be possible, but it's not an easy task, especially because of TypeScript.

@sindresorhus
Copy link
Owner

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
Copy link
Author

ziflex commented Feb 22, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants