sindresorhus / ow

Function argument validation for humans
https://sindresorhus.com/ow/
MIT License
3.81k stars 108 forks source link

Add a `.catching()` method to Predicate to allow nesting ow validators #154

Closed Jblew closed 4 years ago

Jblew commented 5 years ago

I love ow and use it heavily in my TS projects. I use a pattern in which I create a validator function for my interfaces. This validator function uses multiple ow calls to guard the properties. Often an interface is used as a type of a property inside another interface, and that interface also has a validator. It would be very handful if I could just validate this specific property against an already defined validator. Speaking code my pull request allows to do the following:

import ow from "ow";
import { PublishableOperation } from "./PublishableOperation";

export interface PublishJob {
    ops: PublishableOperation[];
    delegator: string;
}

export namespace PublishJob {
    export function validate(job: PublishJob) {
        ow(
            job.ops,
            "job.ops",
            ow.array
                .ofType(ow.object.catching(o => PublishableOperation.validate(o as PublishableOperation))),
        );
        ...
    }
}

This is a way I am achiving it now: https://github.com/wise-team/wise-hub/blob/b0ef49a78ff51e3c8a866513a7d13a68d4b8959a/backend/src/publisher/entities/PublishJob.ts My pull request allows the above way which is far more clean and readable. Of course I've added unit tests for the feature.

I named the method .catching() because it simply catches errors. Also, 'catch' is a keyword and I was not sure it is safe to use it in a property-method context. I am not sure If it is the best name.

I am really looking forward to use this feature!

Thank you in advance, Jędrzej

sindresorhus commented 4 years ago

The feature makes sense. I'm just not convinced on the name. Too me it's not immediately obvious what's happening when reading ow.object.catching.

sindresorhus commented 4 years ago

It feels more like an alternative version / overload of .validate(), but not sure we can reuse the name unambiguously.

SamVerschueren commented 4 years ago

So basically it's a shorthand for this?

const nestedOwValidator = (value: SpecificType) => {
    try {
        ow(value.x, ow.number.finite);
        return true;
    } catch (error) {
        return error.message;
    }
};

const arrayOfNumbers: SpecificType [] = [
    {x: 1},
    {x: Number.POSITIVE_INFINITY}
];

ow(arrayOfNumbers, ow.array.ofType(ow.object.is(o => nestedOwValidator(o))));

I agree that catching does not immediately tell you what it does. Not sure about a better name though 🤔 .

sindresorhus commented 4 years ago

@Jblew Still interested in finishing this?

Jblew commented 4 years ago

Sorry for late response. Interested! .catching can be misleading I agree.

Then — what would you say for .nest(o => ow()) ?

sindresorhus commented 4 years ago

How about .custom()?

sindresorhus commented 4 years ago

Bump

sindresorhus commented 4 years ago

Closing for lack of response.

https://github.com/sindresorhus/ow/issues/188