Here are the codec constructors we have right now:
getCodec: Pretty much runtime validation only since sum types aren't serialisable. (sum <-> sum)
getSerialized: Like getCodec but for the serialised forms. (serialised <-> serialised)
getCodecFromSerialized: Maps between sum types and their serialised forms. (sum <-> serialised)
getCodecFromNullaryTag: Maps between nullary sum types and their tags. (sum <-> tags)
These are good but they're still fairly rigid. Specifically if our internal domain doesn't match the foreign data we're decoding, how can we bring it into the fold? (I guess fairly easily with the experimental io-ts modules... one day...) For example:
type Weather = Sum.Member<'Sun'> | Sum.Member<'Rain'>
type ExternalData = { weather: 'dry' | 'wet' }
We'd need to decode with something like t.union and map the string literals to our sum type after decoding has finished. This PR solves this by adding two new codec constructors:
getCodecFromMappedNullaryTag: Maps between nullary sum types and any arbitrary data using conversion functions. (sum <-> any)
getCodecFromStringlyMappedNullaryTag: Maps between nullary sum types and some other strings. This is more ergonomic than getCodecFromMappedNullaryTag for a more common use case. (sum <-> strings)
Examples are provided in the code (and compiled into the documentation). The above example can now be solved with:
Why nullary sums specifically? io-ts currently requires runtime validation separate from decoding. This is easy for nullary sums for which we simply require an input of all its keys (directly or via the object you see in the example). Non-nullary sums are more difficult and require a codec for their associated values. We could build out another function for that use case, but it's terribly verbose and I'd like to put it off until there's actually a need for it.
Here are the codec constructors we have right now:
getCodec
: Pretty much runtime validation only since sum types aren't serialisable. (sum <-> sum
)getSerialized
: LikegetCodec
but for the serialised forms. (serialised <-> serialised
)getCodecFromSerialized
: Maps between sum types and their serialised forms. (sum <-> serialised
)getCodecFromNullaryTag
: Maps between nullary sum types and their tags. (sum <-> tags
)These are good but they're still fairly rigid. Specifically if our internal domain doesn't match the foreign data we're decoding, how can we bring it into the fold? (I guess fairly easily with the experimental io-ts modules... one day...) For example:
We'd need to decode with something like
t.union
and map the string literals to our sum type after decoding has finished. This PR solves this by adding two new codec constructors:getCodecFromMappedNullaryTag
: Maps between nullary sum types and any arbitrary data using conversion functions. (sum <-> any
)getCodecFromStringlyMappedNullaryTag
: Maps between nullary sum types and some other strings. This is more ergonomic thangetCodecFromMappedNullaryTag
for a more common use case. (sum <-> strings
)Examples are provided in the code (and compiled into the documentation). The above example can now be solved with:
Why nullary sums specifically? io-ts currently requires runtime validation separate from decoding. This is easy for nullary sums for which we simply require an input of all its keys (directly or via the object you see in the example). Non-nullary sums are more difficult and require a codec for their associated values. We could build out another function for that use case, but it's terribly verbose and I'd like to put it off until there's actually a need for it.