我已经搜索了文档,但没有找到针对这种情况的解决方案。我有以下架构。
const RelationSchema = z.object({
guid: z.string(),
createdDate: z.preprocess(castToDate, z.date()),
modifiedDate: z.preprocess(castToDate, z.date()).nullable(),
name: z.string(),
publicationtype: z.string(),
contentType: z.string(),
});
export const NobbRelationsSchema = z.array(NobbRelationSchema);
当使用 NobbRelationsSchema.parse()
解析数组时,我有时会返回 name
作为未定义。在这些情况下,我希望 Zod 不要抛出错误,而只是删除该元素并继续其余部分。一种过滤。
我看到的选项是使用 safeParse
并将 name
设置为可选,然后过滤掉它们。但是,它会扰乱代码中稍后的 TypeScript 类型检查,因为应始终为有效元素设置 name
。
最佳答案
The option I see is to use
safeParse
and set name as optional and filter out these afterwards.
我认为最简单的做法是添加一些特殊的东西,而不是使用 z.array
:安全解析未知数组并过滤它。例如:
import { z } from 'zod';
// -- snip your code here --
type NobbRelation = z.TypeOf<typeof RelationSchema>;
function parseData(data: unknown) {
// First parse the shape of the array separately from the elements.
const dataArr = z.array(z.unknown()).parse(data);
// Next parse each element individually and return a sentinal value
// to filter out. In this case I used `null`.
return dataArr
.map(datum => {
const parsed = RelationSchema.safeParse(datum);
return parsed.success ? parsed.data : null;
})
// If the filter predicate is a type guard, the types will be correct
.filter((x: NobbRelation | null): x is NobbRelation => x !== null);
}
在大多数情况下,这不应该限制您的选择。如果您想对数组施加其他限制(例如最大长度),则可以在处理未知数组时执行此操作。
如果您希望使用变换
进行额外的后处理,您可以在过滤器
之后执行一个步骤。
如果您想要 NobbRelationsSchema
的类型,您可以将其派生为:
type NobbRelations = NobbRelation[]; // Or just write this inline
关于typescript - 如果可用则让 Zod 解析,如果不可用则跳过元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73985439/