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

Predicates should just accept a value and return an error message or undefined #2

Closed
sindresorhus opened this issue Oct 4, 2017 · 7 comments

Comments

@sindresorhus
Copy link
Owner

Right now you have to push it manually to the context. See: #1 (comment)

@SamVerschueren
Copy link
Collaborator

SamVerschueren commented Oct 4, 2017

I'm looking at how this could look like. Not entirely sure how we should do this though. The predicate should return itself to be able to chain it, so we can't do something like this.

minLength(length: number) {
    return (value: string) => {
		if (value.length < number) {
			return `Expected string length to be minimum ${number}`;
		}
    };
}

Have to dig deeper if we have nice way of doing this.

@sindresorhus
Copy link
Owner Author

Maybe we could use Proxies to make it easier?

@sindresorhus
Copy link
Owner Author

Alternatively, we could iterate over each method in our class before using it and wrap it in another function.

@sindresorhus
Copy link
Owner Author

Or maybe use TypeScript decorators.

@SamVerschueren
Copy link
Collaborator

Was thinking about decorators as well. But I think you would then write your logic in your decorator :p. Going to experiment with proxies first.

@Predicate({
    message: 'Value should be alphanumeric',
    validator: x => /^[0-9\d]+$/i.test(x)
})
get alphanumeric() {
    return this;
}

@sindresorhus
Copy link
Owner Author

That looks weird. I was thinking the predicate decorator didn't take any arguments but instead wrapped the following function so it would return this, but I still think Proxy might be easier. I like your separation of message and validation though.

@SamVerschueren
Copy link
Collaborator

SamVerschueren commented Oct 7, 2017

I tried a bunch of things in the meantime. Not sure we could actually make this work with automatic type definitions.

This is what I got

export class StringPredicate extends Predicate {

	constructor(context?: Context) {
		super('string', context);
	}

	@Validator()
	minLength(number: number) {
		return {
			message: () => `Expected string length to be minimum ${number}`,
			validator: (value: string) => value.length < number
		};
	}
}

The thing is that de type definitions think that I return an object with message and validator although I change the return type with the decorator.
So this actually works perfectly, the only thing is that the type definitions do not match with what we're having at runtime... I'm looking into it, if we can change that behaviour but I don't think we can.
Keep you posted!

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