Open GioAc96 opened 2 years ago
Allowing zero arguments on t.tuple
will not allow you to construct an empty array codec because internally the implementation is slicing away all additional values which is not considered an error. So you will need to implement it by yourself anyway.
Of course, I'm not suggesting that only the signature of the t.tuple
method is changed, but the implementation would be changed as well to allow empty tuples. io-ts proudly implements most features of the typescript type system, it's weird that it does not account for something as simple as an empty tuple type.
I think this change will not happen cause it would introduce a breaking change in the behavior and it seems to be intended by @gcanti. You can see that is explicitly tested here: https://github.com/gcanti/io-ts/blob/master/test/2.1.x/tuple.ts#L71-L75
The behavior seems to be the same as with type
and interface
where additional properties will not result in a failure during a decoding.
I really don't see how this feature would introduce a breaking change, since it would loosen the requirements for the first argument of the tuple
combinator. Also, the test that @mlegenhausen linked checks that additional components are stripped from the tuple, which has little to do with the requested feature. An empty tuple would simply strip all properties from the input, although I understand that this could cause some confusion since the codec t.tuple([])
would decode any array/tuple to an empty tuple. However, this is already not aligned with Typescript's behaviour, since the type checker already complains about additional components, as shown here:
type EmptyTuple = []
const a: EmptyTuple = ['hola'] // error: Source has 1 element(s) but target allows only 0
type StringNumberTuple = [string, number]
const b: StringNumberTuple = ['hola', 1, true] // error: Source has 3 element(s) but target allows only 2
Maybe @gcanti has more insights about why the tuple combinator was designed to reject empty tuples
t.tuple([])
is currently a compiler error so this shouldn't be a breaking change.
As @mlegenhausen pointed out, the current t.tuple
implementation ignores any extra elements. To be consistent with that t.tuple([])
would have to accept any array, since any array is a 0-tuple as long as you ignore all the elements. Therefore, adding 0-tuple support to the current t.tuple
implementation is not very useful. See #503 for more general discussion about tuple length validation.
🚀 Feature request
Current Behavior
Currently, the
tuple
combinator requires at least one codec, preventing it to be used as an empty tuple codecDesired Behavior
Allow the
tuple
combinator to also accept an empty array of codecs:Alternatives
The same codec can also be implemented as follows:
This alternative works just fine, but I don't understand why io-ts would impose a tuple to have at least one codec in it while typescript supports the empty tuple type
[]
Additional context
I found myself looking for this feature while building a codec to encode an http response that would have an empty array
errors
field in case of success. I am aware that omitting theerrors
field when no errors occur would be a better solution, but that is not an option in my case.My environment