valibot
valibot copied to clipboard
Pipe not applying on tuple with only the items parameter
Hi, I think I found a bug on the tuple schema.
If I create a schema tuple([number()], string(), [maxLength(1)]) (items, rest & pipe) and try to parse against [1, 'a'], as expected, I get an Invalid length error.
But if I create a schema tuple([number()], [maxLength(1)]) (items & pipe) and try to parse against [1, 2], I don't get any error.
This is expected since v0.20.0. 🤓 If no rest argument is given, tuple ignores all potential rest items. This means that they will not be in the output and the tuple is therefore valid. Also, maxLength makes no sense for a tuple without a rest argument, since it has a fixed length.
The current implementation allows the developer to decide whether to simply ignore potential rest elements (the default) or to deliberately prevent them by using never() for the rest argument. So tuple has the same behavior as object. However, I understand that there will be different opinions on this, and I am interested in hearing them.
Ok I see the logic here. And I think I will prefer using tuple([number()], never()) rather than tuple([number()], [maxLength(1)]).
However, it's still a bit weird that length constraint are forced inside the tuple implementation when no rest parameter is provided.
If I understand correctly tuple([number()]) is equivalent to tuple([number()], any()), right ?
If so, then isn't it weird that tuple([number()], [maxLength(1)]) is not equivalent to tuple([number()], any(), [maxLength(1)]) ?
Yes, as I said, tuple behaves in the same way as object and removes everything that is not defined by default. Basically, it removes what you are not interested in either way. Via the rest argument you can change this behaviour. With tuple([number()], never()) you can make your tuple strict and with tuple([number()], string()) you can allow any other data type, in the example strings, as the tuple rest.
The alternative to this would be to make it strict by default and throw an error if the length of the input does not match the tuple length. However, this would have the consequence that this behavior could not or only hardly be changed afterwards.
tuple([number()]) is not the same as tuple([number()], any()). The type signature is different and so also the output.
Even if I leave it as it is for now, I am very interested in further feedback and ideas. But we should find a final solution by v1.
Ah ok I see now, thanks !
Please let me know if you have any ideas how to improve this or any other issue. I plan to publish v1 in January.
I don't have a better idea no. But a good documentation of tuple would certainly help :)
I agree! Thanks for pointing that out!
I will close this issue as our pipeline implementation has completely changed.