两个[或更多]解码器的交集

Intersection of two [or more] decoders

假设已经定义了两个解码器:

import * as D from "decoders"
const named = D.object({
  firstName: D.string,
  lastName: D.string
})

const aged = D.object({
  age: D.number
})

我如何获得这些现有解码器的 交集,以便它验证包含两者属性的 object

const person: D.Decoder<{
  firstName: string,
  lastName: string,
  age: number
}> = D.???(named, aged)

图书馆似乎没有这方面的功能。
这是如何完成的

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);

或者如果解码器是 inexact 而不是 object:
(如果它们不是 inexact 并且类型检查器不会捕获它,这将失败)

function combine<A, B>(d1: D.Decoder<A>, d2: D.Decoder<B>) {
  return D.compose(d1, d2) as unknown as D.Decoder<A & B>;
}