0

使用DecoderAPI,有没有办法定义具有互斥属性的解码器?

import * as D from 'io-ts/Decoder';

const decoder = pipe(
  D.struct({
    a: D.string
  }),
  D.intersect(
    D.partial({
      b: D.string,
      c: D.boolean
    })
  )
);

以上设置了一种情况,其中bc都可以存在,但都是可选的。相反,我怎么能要求其中一个bc 必须存在,而不是两者都存在?

4

1 回答 1

0

您可以使用Union 组合器。

const decoder = pipe(
  D.struct({
    a: D.string
  }),
  D.intersect(
    D.union(
      D.struct({ b: D.string }),
      D.struct({ c: D.string })
    )
  )
);

请记住,您将无法访问bc不首先检查这些属性是否存在,因为 Typescript 无法知道您的对象中存在这两者中的哪一个。

type Decoder = D.TypeOf<typeof decoder>
declare const myDecoder: Decoder;

myDecoder.a // inferred as `string`
myDecoder.b // TYPE ERROR: Property 'b' does not exist on type '{ a: string; } & { c: string; }'
myDecoder.c // TYPE ERROR: Property 'c' does not exist on type '{ a: string; } & { b: string; }'

if ("b" in myDecoder) {
  myDecoder.b // inferred as `string`
}

if ("c" in myDecoder) {
  myDecoder.c // inferred as `string`
}

请注意,在检查这两个互斥属性时,您会收到类型错误。TypeScript 正确地推断出这是一种永远不会发生的情况(myDecoder推断为neverif块内)

if ("b" in myDecoder && "c" in myDecoder) {
  myDecoder.b // TYPE ERROR: Property 'b' does not exist on type 'never'.
  myDecoder.c // TYPE ERROR: Property 'c' does not exist on type 'never'.
}
于 2021-07-28T07:35:25.077 回答