【问题标题】:Make Zod parse if available, and if not skip element如果可用,则进行 Zod 解析,如果没有则跳过元素
【发布时间】:2022-10-08 12:42:26
【问题描述】:

我已经搜索了文档,但没有找到适合这种情况的解决方案。我有以下模式。

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

【问题讨论】:

    标签: typescript zod


    【解决方案1】:

    我看到的选项是使用safeParse 并将名称设置为可选,然后过滤掉这些。

    我认为最简单的做法是添加一些特殊的东西而不是使用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);
    }
    

    在大多数情况下,这不应限制您的选择。如果您想对array 施加其他限制,例如最大长度,您可以在处理未知数组时执行此操作。

    如果您想对transform 进行额外的后期处理,您可以在filter 之后执行该操作。

    如果您想拥有NobbRelationsSchema 的类型,您可以将其派生为:

    type NobbRelations = NobbRelation[]; // Or just write this inline
    

    【讨论】:

      猜你喜欢
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多