typescript - 如果可用则让 Zod 解析,如果不可用则跳过元素

标签 typescript zod

我已经搜索了文档,但没有找到针对这种情况的解决方案。我有以下架构。

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/

相关文章:

next.js - 如何在 Zod 中基于单选按钮选择对文件输入字段实现条件验证?

typescript - Zod 不需要任何字段或两个字段都需要

arrays - 在 TypeScript 中,如何声明接受字符串并返回字符串的函数数组?

angular - 如何将表单控件值传递给 Angular 5 react 表单中的自定义验证器函数的参数

generics - 在 TypeScript 泛型中使用 "extends"关键字

reactjs - 基于表单字段的zod条件验证

typescript - 检查 Zod 类型是否等同于 TypeScript 接口(interface)?

javascript - 如何使用 Zod 的 isEmail?

typescript - 在处理 Angular2-typescript 项目时如何在 WebStorm 中隐藏 .js 和 .map 文件

javascript - 为什么 Chrome 在 TypeScript 中显示\ufeff 符号和灰线?