Let's say two decoders are already defined:
import * as D from "decoders"
const named = D.object({
firstName: D.string,
lastName: D.string
})
const aged = D.object({
age: D.number
})
How do I get an intersection of these existing decoders, such it validates for an object
containing properties from both?
const person: D.Decoder<{
firstName: string,
lastName: string,
age: number
}> = D.???(named, aged)
It doesn't look like the library has a function for that.
Here is how it could be done
import { Ok } from "lemons/Result";
function combine<A, B>(decoder1: D.Decoder<A>, decoder2: D.Decoder<B>): D.Decoder<A & B> {
return (blob: unknown) =>
decoder1(blob).andThen((v1) => decoder2(blob).andThen((v2) => Ok({ ...v1, ...v2 })));
}
const person = combine(aged, named);
Or if the decoders are inexact
instead of object
:
(This will fail if they are not inexact
and the type checker won't catch it)
function combine<A, B>(d1: D.Decoder<A>, d2: D.Decoder<B>) {
return D.compose(d1, d2) as unknown as D.Decoder<A & B>;
}