如果我正确理解您要查找的内容,您已经有一个 TypeC 编解码器,并且正在尝试创建一个新编解码器来检查该基本编解码器的可能值的联合?您正在寻找的 TypeScript 类型会是这样的吗?
type valuesOfCodec<T> = t.Type<T[keyof T>, T[keyof T], unknown>;
编解码器将在哪里解码给定接口的值。
我认为io-ts 不支持开箱即用,但我能够编写一个快速函数来创建一个给定TypeC 的编解码器。
// This helper is needed because `t.union` expects at least two codecs
function hasAtLeastTwoItems<T>(t: T[]): t is [T, T, ...T[]] {
return t.length > 1;
}
// This is the main helper which pulls the value codecs out of a t.TypeC
function valuesOf<T extends t.Props>(
type: t.TypeC<T>
): t.Type<t.TypeOfProps<T>[keyof T], t.TypeOfProps<T>[keyof T], unknown> {
const valueCodecs: t.Mixed[] = [];
for (const key of Object.keys(type.props)) {
// Grab all of the value codecs out of the iterable properties of the
// input type's `props` field.
valueCodecs.push(type.props[key]);
}
// If the original type has at least two fields, we can make a union
// out of the values.
if (hasAtLeastTwoItems(valueCodecs)) {
return t.union(valueCodecs);
}
// If the type has one field, then the value codec will just be that
// fields codec.
if (isNonEmpty(valueCodecs)) {
return valueCodecs[0];
}
// If the type has no fields, then we shouldn't really be decoding
// successfully at all so I just threw together this `t.Type` that
// never succeeds at decoding.
return new t.Type<unknown, unknown, unknown>(
"always fail",
(x): x is unknown => false,
(i, c) => t.failure(i, c, "Cannot decode this codec"),
(i) => i
);
}
const FilterUnionTypeC = valuesOf(FilterTypeC);
console.log(FilterUnionTypeC.decode("POTATO")); // -> Right<...>
这应该可以解决问题,但我会稍微警告一下,这依赖于 t.TypeC 类中存在的特殊元数据,因此即使 A 类型是记录/接口,这也不适用于其他编解码器.