mojotech / json-type-validation

TypeScript JSON type validation
MIT License
155 stars 15 forks source link

Possible to represent fixed-length arrays / "tuples"? #31

Closed r-k-b closed 5 years ago

r-k-b commented 5 years ago

What would a decoder for type [number, number, number] look like?

For example,

import { array, Decoder, number } from '@mojotech/json-type-validation'

type customTuple = [number, number, number]

const tupleDecoder: Decoder<customTuple> = array(number())

results in:

Error:(5, 7) TS2322: Type 'Decoder<number[]>' is not assignable to type 'Decoder<[number, number, number]>'.
  Type 'number[]' is not assignable to type '[number, number, number]'.
    Property '0' is missing in type 'number[]'.
mulias commented 5 years ago

So here's my first thought. It's gross and unwieldy, but it should work.

const tupleDecoder1: Decoder<customTuple> = 
  valueAt([0], number()).andThen((n0) =>
    valueAt([1], number()).andThen((n1) =>
      valueAt([2], number()).andThen((n2) =>
        [n0, n1, n2])))

With TS 3.1+ we have mapped tuple types, which I think we can use to export a new decoder that has a much cleaner interface. Ideally that would look this:

const tupleDecoder2: Decoder<customTuple> = tuple([number(), number(), number()]);

If you'd like to try you hand at implementing that, it's going to be kind of a combination of the array and object decoders -- in particular it will use the DecoderObject mapped type in a very similar way to object. Otherwise maybe I'll try it out over the holidays.

erikmaarten commented 5 years ago

This would be great. I might try implementing this, if @r-k-b is not planning to.

r-k-b commented 5 years ago

Fixed in #32 .