Closed IlyaSemenov closed 1 month ago
Thanks for the feedback. I will check if I want to export these types, but in general it is probably a good idea. nonEmpty
is now natively supported out of the box, so you don't have to add it yourself.
In general, there is no difference from before. The only difference is that the API has become more type-safe, which requires more precious typing, resulting in more TypeScript code. But if you don't care, you can write it much the same way as before. Here is an example. You can test it in this playground.
import * as v from 'valibot';
type LengthInput = string | unknown[];
function nonEmpty<TInput extends LengthInput>(
message: string = 'Non-empty value required.'
): v.MinLengthAction<TInput, 1, string> {
return v.minLength(1, message);
}
If you prefer precise types, I have rewritten your code to make it a bit simpler. You can test it in this playground.
import * as v from 'valibot';
type LengthInput = string | unknown[];
function nonEmpty<
TInput extends LengthInput,
const TMessage extends v.ErrorMessage<v.MinLengthIssue<TInput, 1>>,
>(
message: TMessage = 'Non-empty value required.' as TMessage
): v.MinLengthAction<TInput, 1, TMessage> {
return v.minLength(1, message);
}
Another use case is:
export function integerNumber<TMessage extends v.ErrorMessage<v.NumberIssue>>(message?: TMessage) {
return v.pipe(v.number(message), v.integer())
}
is there a better way to type this? Most of the schemas use function overload to distinguish between the message and undefined:
declare function number(): NumberSchema<undefined>;
declare function number<const TMessage extends ErrorMessage<NumberIssue> | undefined>(message: TMessage): NumberSchema<TMessage>;
Is there a way to proxy this contract somehow to the extending one-liners?
As I understand it, this is not possible without drawbacks. That's why I use overload signatures.
I added ContentInput
, ContentRequirement
, LengthInput
, SizeInput
and ValueInput
to the exports.
Before the new pipe API, I was creating ad-hoc validators with something like:
after the update, the least I could come up with was:
If I remove the function definition boilerplate and only keep the last 3 lines, it works but it's not typed properly:
My question is, can we come up with some kind of approved recipe and/or reduced boilerplate for trivial library extensions such as above? In my perfect world, it should be possible to come up with multitude of similar one-liners, not having to toss unreadable mess of copy/pasted generics.