typescript - 没有使用 io-ts 进行未定义验证的数组
问题描述
我们正在使用io-ts来验证来自 HTTP 服务的外部数据。我编写了一个编解码器,它采用另一个编解码器C
并返回Either<t.Errors, C | undefined>
但实际上从未失败(只是为了满足t.Type
)。这是因为从服务中我们得到了不同类型的数组,并且将来可以添加新的类型,因此我们希望它继续工作,但忽略那些未定义的。好像:
export function tryDecode<C extends io.Mixed>(
codec: C,
onLeft?: (validation: io.Validation<unknown>) => void,
) {
return new io.Type<io.TypeOf<C> | undefined, io.OutputOf<C>, unknown>(
'tryDecode',
(input: unknown): input is C | undefined => {
return codec.is(input) || input === undefined;
},
(u, c) => {
const validation = codec.validate(u, c);
return fold(
() => {
if (onLeft) {
onLeft(validation);
}
return io.success(undefined as C | undefined);
},
(right: C | undefined) => io.success(right),
)(validation);
},
io.identity,
);
}
我正在尝试编写一个arrayWithoutUndefined
类似io.array
但删除任何未定义元素的编解码器。它不应该失败(除非它不是一个数组)。到目前为止我的尝试:
export function arrayWithoutUndefined<C extends io.Mixed>(
codec: C,
name = `arrayWithoutUndefined<${codec.name}>`,
) {
const arr = io.array(codec);
return new io.Type(
name,
(u): u is Array<io.TypeOf<C>> => arr.is(u) && !u.includes(undefined),
(u, c) =>
either.chain(codec.validate(u, c), as =>
io.success(as.filter(notUndefined)),
),
arr.encode,
);
}
是notUndefined
确保(a: A | undefined): a is A => ...
. 然后我会将它们一起使用,const Modules = arrayWithoutUndefined(tryDecode(UnionOfDifferentModules))
但 Modules 仍然表示为Array<UnionOfDifferentModules | undefined>
当我希望它只是Array<UnionOfDifferentModules>
. 这可以用 TypeScript/io-ts 以某种方式表达吗?我研究了条件类型,但不幸的是不知道如何表达。
解决方案
在支持数组过滤语句中的类型保护的较新版本的打字稿中,这个问题可能已经解决了。
的显式泛型也可能在t.Type
这里有所帮助。
type Subtract<A, B> = A extends B ? never : A;
return io.Type<Subtract<t.TypeOf<C>, undefined>, unknown[], unknown>(...);
推荐阅读
- java - 我将如何处理并行数组以在 java 中存储不同类型的信息
- css - 隐藏 MatPaginator 详细信息
- spring-boot - 如何使用 rsocket 在 Spring Boot 中配置 SSL/TLS?
- python - Python向客户端发送请求POST标头授权(vuejs)
- java - 如何重复倒数计时器一定次数
- python - Excel 和 CSV 仍在进行中,我无法真正编辑 Excel 文件
- python - 有没有办法暂时暂停 Shady 中的所有世界/刺激动态?
- regex - 有人可以为我提供一个匹配 1986-04-02 或 XXXX-XX-XX 的 DOB 正则表达式吗
- java - 我没有得到最后一行的所有 25 个字母
- node.js - 从 jeft 连接查询中选择特定列,TypeORM