1

目前我正在开发一个具有 fp-ts 和 io-ts 堆栈的项目。我正在尝试验证我们从后端获得的所有响应io-ts。我开始知道io-ts没有简单的方法来制作optional. typescript并从这个问题中找到了一种解决方法来制作带有可选字段的对象。

我想创建看起来像这样的类型。

type finalType = {
  req: string;
  opt?: string;
};

在我们的项目中,我们有这个runDecoder函数来验证响应数据的io-ts类型。它适用于非可选的普通io-ts类型。

但是当它试图验证在类型的帮助下成为可选的类型时,问题就出现了t.intersection。这是带有示例的代码

import * as Either from "fp-ts/lib/Either";
import * as io from "io-ts";

export const runDecoder = <T extends io.Props>(type: io.TypeC<T>) => (
  data: unknown
) => {
  const result = type.decode(data);
  if (Either.isLeft(result)) {
    return Error("error");
  }
  return result.right;
};

// I want to create type something like this
// type finalType = {
//   req: string;
//   opt?: string;
// };

const OptionType = io.partial({
  opt: io.string
});

const RequiredType = io.type({
  req: io.string
});

const FinalType = io.intersection([RequiredType, OptionType]);

type resultType = io.TypeOf<typeof FinalType>;

const respose:resultType = {
  req: "str"
};

const decoded = runDecoder(FinalType)(respose);

我得到的错误是

Argument of type 'IntersectionC<[TypeC<{ req: StringC; }>, PartialC<{ opt: StringC; }>]>' is not assignable to parameter of type 'TypeC<Props>'.
  Property 'props' is missing in type 'IntersectionC<[TypeC<{ req: StringC; }>, PartialC<{ opt: StringC; }>]>' but required in type 'TypeC<Props>'.

我试图理解错误,但我无法用runDecoder方法弄清楚这里有什么问题。这是Codesandbox链接。任何帮助将不胜感激。

4

1 回答 1

1

问题是那FinalType是一个IntersectionType,而runDecoder接受一个TypeC

Type<A, O, I>
├ InterfaceType<P, A, O, I>     (+ readonly props: P)
│ └ TypeC<P extends Props>
└ IntersectionType<CS, A, O, I> (+ readonly types: CS)

我还没有使用过 io-ts,但在我看来,这个InterfaceType类(以及TypeC扩展它的接口)似乎只适用于简单对象类型(如{req: string; opt?: string})的编解码器,而不适用于交集类型(如{req: string} & {opt?: string}) . 尽管 TypeScript 中的这些类型在语义上可能是等价的,但它们在 io-ts 中的表示方式不同。

您得到的错误是由于FinalType没有props所需的属性,InterfaceType因为FinalTypeIntersectionType.

我会runDecoder简单地接受 aType甚至 a DecoderType扩展):

// I: input type
// A: output type
export const runDecoder = <I, A>(type: io.Decoder<I, A>) => (
  data: I
): A | Error => {
  // ...
}

代码沙盒

于 2021-08-03T10:50:02.867 回答