交叉口类型的 io-ts 解码器错误
Io-ts decoder error for intersection type
目前我正在做一个有 fp-ts 和 io-ts 栈的项目。我正在尝试使用 io-ts
验证我们从后端获得的所有响应。我开始知道 io-ts
没有简单的方法来制作 optional
类型的 typescript
。
从这个 issue 找到了一个变通方法来制作带有可选字段的对象。
我想创建看起来像这样的类型。
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
方法有什么问题。这里是Codesandboxlink。
任何帮助将不胜感激。
问题是 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
class(因此也是扩展它的 TypeC
接口)是仅适用于简单对象类型(如 {req: string; opt?: string}
)的编解码器,不适用于交集类型(如 {req: string} & {opt?: string}
)。尽管 TypeScript 中的这些类型在语义上可能是等价的,但它们在 io-ts 中的表示方式不同。
您收到的错误是由于 FinalType
没有 InterfaceType
中所需的 props
属性,因为 FinalType
是一个 IntersectionType
.
我会让 runDecoder
接受简单的 Type
or even a Decoder
(Type
扩展):
// I: input type
// A: output type
export const runDecoder = <I, A>(type: io.Decoder<I, A>) => (
data: I
): A | Error => {
// ...
}
目前我正在做一个有 fp-ts 和 io-ts 栈的项目。我正在尝试使用 io-ts
验证我们从后端获得的所有响应。我开始知道 io-ts
没有简单的方法来制作 optional
类型的 typescript
。
从这个 issue 找到了一个变通方法来制作带有可选字段的对象。
我想创建看起来像这样的类型。
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
方法有什么问题。这里是Codesandboxlink。
任何帮助将不胜感激。
问题是 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
class(因此也是扩展它的 TypeC
接口)是仅适用于简单对象类型(如 {req: string; opt?: string}
)的编解码器,不适用于交集类型(如 {req: string} & {opt?: string}
)。尽管 TypeScript 中的这些类型在语义上可能是等价的,但它们在 io-ts 中的表示方式不同。
您收到的错误是由于 FinalType
没有 InterfaceType
中所需的 props
属性,因为 FinalType
是一个 IntersectionType
.
我会让 runDecoder
接受简单的 Type
or even a Decoder
(Type
扩展):
// I: input type
// A: output type
export const runDecoder = <I, A>(type: io.Decoder<I, A>) => (
data: I
): A | Error => {
// ...
}