unsplash / sum-types-io-ts

io-ts bindings for @unsplash/sum-types.
https://unsplash.github.io/sum-types-io-ts/
MIT License
2 stars 1 forks source link

Add nullary mapped codec constructors #9

Closed samhh closed 2 years ago

samhh commented 2 years ago

Here are the codec constructors we have right now:

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:

Examples are provided in the code (and compiled into the documentation). The above example can now be solved with:

const ExternalData = t.type({
  weather: getCodecFromStringlyMappedNullaryTag<Weather>()({ Sun: 'dry', Rain: 'wet' }),
})

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.