Zod进行TypeScript类型验证使用详解

目录
  • 引言
  • 什么是类型验证,为什么需要它?
  • 为什么要使用zod?
  • 使用 Zod 进行类型验证的示例
    • Primitives
    • 对象
    • 类型推断
    • 组合类型
    • 注意事项
    • 安全解析
    • 无法识别的Key被删除
    • 其他事项
  • Zod 与其他库的比较
  • 结论

引言

这篇文章将描述如何使用Zod为您的项目设置类型验证。Zod 是一个用于类型声明和验证的开源 TypeScript 库。我们将研究为什么使用 Zod 进行类型验证,提供如何使用它的示例,并将其与其他库进行比较。

什么是类型验证,为什么需要它?

类型验证是验证数据结构是否符合特定类型的过程。您可以使用它来确保输入数据的有效性,以及记录和执行代码的数据结构。

使用类型验证有两个主要好处:

  • 运行时的数据完整性:确保数据以正确的格式输入您的系统有助于避免错误并保持数据一致性。虽然 TypeScript 可以帮助您在编译时确保类型安全,但当您处理来自未知数据(例如服务器或用户输入)的数据时,类型验证在运行时会大放异彩。
  • 文档:一个好的类型验证库将为您使用的数据结构提供准确的类型定义。类型定义可用于为您的项目生成静态文档。

为什么要使用zod?

虽然有许多 TypeScript 类型校验库,但个人认为 Zod 是比较好的之一。在为您的项目选择库时,除了其功能集外,您还应考虑其实现细节。

  • Zod 具有零依赖性,这意味着您可以在没有任何其他库的情况下安装和使用 Zod,它将帮助您保持更小的包大小。
  • Zod 适用于 Node.js 和所有主流浏览器(包括 IE 11)。这使其成为需要支持各种平台的项目的不错选择。
  • Zod 被设计为 TypeScript 优先,这意味着该库将自动为您的数据结构推断静态 TypeScript 类型。这消除了两次声明类型的需要——一次在 Zod 中,一次在 TypeScript 中。它将为您节省大量输入,并帮助您保持代码更改同步。
  • Zod 的 API 简洁且可链接。这使得创建复杂的数据类型变得容易。您还可以轻松地将更简单的类型组合成更复杂的数据类型。

使用 Zod 进行类型验证的示例

Primitives

让我们看看如何验证字符串。假设我们要验证用户输入的密码。我们希望密码是一个非空字符串,长度至少为 8 个字符,最多为 32 个字符:

import { z } from "zod";
const stringSchema = z.string().nonempty().min(8).max(32);
stringSchema.parse("");
stringSchema.parse(""); // throws an exception
stringSchema.parse("I am a valid password"); // returns "I am a valid password"

当你运行上面的代码时,你会看到 parse 方法抛出了一个异常。异常将包含一个对象数组,其中包含ZodError错误的详细描述:

    [
      {
      "code": "too_small",
      "minimum": 1,
      "type": "string",
      "inclusive": true,
      "message": "Should be at least 1 characters",
      "path": []
      },
      {
      "code": "too_small",
      "minimum": 8,
      "type": "string",
      "inclusive": true,
      "message": "Should be at least 8 characters",
      "path": []
      }
    ]

当您尝试解析有效字符串时,parse 将简单地返回其值。

对象

现在让我们继续讨论对象。Zod 对验证嵌套对象结构具有强大的支持。

让我们创建一个类型来验证用户对象。它将包含以下字段:

  • 姓名
  • 电子邮件
  • 电话号码

要声明类型,我们使用z.object() 方法:

    import { z } from "zod";
    const User = z.object({
      email: z.string().email(),
      name: z.string(),
      phoneNumber: z.number()
    });

让我们尝试根据我们刚刚创建的类型验证示例对象:

    const result = User.parse({
      email: "hi@sample.com",
      name: "Hello World"
    });

parse方法将返回一个包含解析结果的对象。由于我们忘记在示例中提供该phoneNumber字段,Zod 将抛出异常,并包含以下错误数组:

    [
      {
      "code": "invalid_type",
      "expected": "number",
      "received": "undefined",
      "inclusive": true,
      "message": "Required"
      "path": ["phoneNumber"]
      }
    ]

类型推断

我们还可以从对象中推断出类型。这是您可以免费获取属性的类型定义并在您的代码中使用它们的部分:

    type UserType = z.infer<typeof User>;

组合类型

Zod 让您可以轻松地在彼此之上组合复杂的类型,就像您构建乐高积木一样。

为了证明这一点,让我们使用User上面的类型对象并构建一个更详细的具有爱好的用户对象:

    const User = z.object({
      email: z.string().email(),
      name: z.string(),
      phoneNumber: z.number()
    });
    const Hobby = z.object({
      hobbyName: z.string().min(1)
    });
    const Hobbyist = User.merge(Hobby);
    const result = Hobbyist.safeParse({
      email: "hi@sample.com",
      name: "Hello World",
      phoneNumber: 123
    });

通过组合我们的两个类型对象,我们创建了一个新类型对象,您可以使用它来验证用户对象是否具有适当的爱好字段。

在现有对象之上组合新对象是一种很好的方法,因为它可以帮助您保持数据结构中的所有更改同步。

注意事项

在使用 Zod 进行验证时,需要牢记几件事。

安全解析

如果不想让Zod抛出异常,当解析失败时,可以改用该safeParse方法。这将返回一个包含解析结果的对象:

 mySchema.safeParse(""I am a valid password""); // => { success: true; data: "I am a valid password" }
 mySchema.safeParse(""); // => { success: false; error: ZodError }

无法识别的Key被删除

默认情况下,Zod 在解析过程中会去除无法识别的key。这意味着任何未知的key都将被忽略。

如果您想通过无法识别的key而不丢失它们,您可以使用该.passthrough()方法。

其他事项

.array() 方法返回一个新的 ZodArray 实例,这意味着调用方法的顺序很重要。通过切换链中调用的顺序,您可以获得完全不同的结果:

z.string().optional().array(); // (string | undefined)[]
z.string().array().optional(); // string[] | undefined

Zod 与其他库的比较

其他广泛使用的类型验证库也是不错的选择,例如 yupio-ts

以下是您项目的选择Zod 的一些原因:

  • TypeScript 首次支持。Zod 在构建时考虑了 TypeScript,并具有一流的支持。这意味着您可以获得自动完成和出色的 VsCode 支持。
  • 无需额外工作即可为您获取类型。
  • 易于组合的类型对象 - 通过组合不同的类型对象来构建复杂的验证规则。
  • 强大的错误处理。Zod 具有出色的错误处理功能,具有丰富的 API 用于配置错误处理流程。
  • 支持 Promise 和函数模式。如果您需要验证函数或 Promise,Zod 可以满足您的需求。

结论

在这篇文章中,我们介绍了如何使用 Zod 库进行 TypeScript 类型验证。我们研究了如何创建类型和使用类型来验证数据结构。我们还看到了使用 Zod 时需要注意的一些事项以及它相对于其他库的优势。

有关 Zod 的更多信息,可以查看其 Github 页面上的优秀文档 。

更多关于Zod TypeScript类型验证的资料请关注我们其它相关文章!

(0)

相关推荐

  • TypeScript判断对称的二叉树方案详解

    目录 前言 实现思路 实现代码 示例代码 前言 如果一颗二叉树和它的镜像一样,那么它就是对称的.实现一个函数用于判断一颗二叉树是否对称,你会怎么做? 本文将分享一种解决方案,欢迎各位感兴趣的开发者阅读本文. 实现思路 在上一篇文章二叉树的镜像中我们知道了此问题的解决方案是前序遍历,那么我们可以修改下前序遍历算法,父节点遍历后,先遍历它的右子节点,再遍历它的左子节点,我们把这种算法称为:对称前序遍历 如下图所示的两棵树,我们分别列举下两种遍历的结果: 树A: 前序遍历:8, 6, 5, 7, 6,

  • Typescript 封装 Axios拦截器方法实例

    目录 引言 创建 class axios.create([config]) 封装 request(config)通用方法 封装-拦截器(单个实例独享) 扩展 Http 自定义拦截器 封装-拦截器(所有实例共享) 封装-拦截器(单个请求独享) 装修 Http class 返回经过 request 返回数据结构(DTO) 拦截器执行顺序 操作场景控制 引言 对 axios 二次封装,更加的可配置化.扩展性更加强大灵活 通过 class 类实现,class 具备更强封装性(封装.继承.多态),通过实例

  • 在React项目中使用TypeScript详情

    目录 项目目录及ts文件划分 在项目中使用TypeScript具体实践 组件声明 React Hooks使用 useState useRef useCallback useMemo useContext useReducer useImperativeHandle Axios请求/响应定义封装 前言: 本文主要记录我如何在React项目中优雅的使用TypeScript,来提高开发效率及项目的健壮性. 项目目录及ts文件划分 由于我在实际项目中大部分是使用umi来进行开发项目,所以使用umi生成的

  • TypeScript数组实现栈与对象实现栈的区别详解

    目录 前言 数组实现栈 实现思路 实现代码 编写测试代码 对象实现栈 实现代码 编写测试代码 二者的区别 十进制转二进制 前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时,那么栈这种数据结构将是你的首选. 栈的实现方式一般有两种:数组实现和对象实现,这两种实现方式最终实现的功能都是一样的,但是在性能上却有着很大的差别. 本文将详细讲解这两种实现方式的差异并用TypeScript将其实现,欢迎各位感兴趣的开发者阅读本文. 数组实现栈 本文讲解的是栈用代码的实现,如

  • TypeScript获取二叉树的镜像实例

    目录 前言 思路分析 实现代码 前言 给定一颗二叉树,如何获取它的镜像?本文将跟大家分享这个问题的解决方案,欢迎各位感兴趣的开发者阅读本文. 思路分析 当我们把一张写有文字的纸放在镜子前面,你看到的内容正好与你写的内容是相反的.那么我们就可以依据照镜子的经验画出它的镜像了,如下所示: 镜像前后的两棵树根节点相同 镜像后的树与镜像前相比:它们的左.右子节点交换了位置 通过观察后,我们就得出了一颗树的镜像过程:先序遍历这棵树的每个节点,如果遍历到的节点有子节点,就交换它的两个子节点.当交换完所有非叶

  • 前端算法之TypeScript包含min函数的栈实例详解

    目录 前言 思路梳理 实现代码 示例代码 前言 基于数据结构: “栈”,实现一个min函数,调用此函数即可获取栈中的最小元素.在该栈中,调用min.push.pop的时间复杂度都是O(1). 本文就跟大家分享下这个算法,欢迎各位感兴趣的开发者阅读本文. 思路梳理 相信大多数开发者看到这个问题,第一反应可能是每次往栈中压入一个新元素时,将栈里的所有元素排序,让最小的元素位于栈顶,这样就能在O(1)的时间内得到最小元素了.但这种思路不能保证最后入栈的元素能够最先出栈,因此这个思路行不通. 紧接着,我

  • Zod进行TypeScript类型验证使用详解

    目录 引言 什么是类型验证,为什么需要它? 为什么要使用zod? 使用 Zod 进行类型验证的示例 Primitives 对象 类型推断 组合类型 注意事项 安全解析 无法识别的Key被删除 其他事项 Zod 与其他库的比较 结论 引言 这篇文章将描述如何使用Zod为您的项目设置类型验证.Zod 是一个用于类型声明和验证的开源 TypeScript 库.我们将研究为什么使用 Zod 进行类型验证,提供如何使用它的示例,并将其与其他库进行比较. 什么是类型验证,为什么需要它? 类型验证是验证数据结

  • TypeScript类型声明书写详解

    本文总结一下TypeScript类型声明的书写,很多时候写TypeScript不是问题,写类型就特别纠结,我总结下,我在使用TypeScript中遇到的问题.如果你遇到类型声明不会写的时候,多看看lodash的声明,因为lodash对数据进行各种变形操作,所以你能遇到的,都有参考示例. 基本类型 // 变量 const num: number = 1; const str: string = 'str'; const bool: boolean = true; const nulls: null

  • TypeScript的类型指令单行注释详解

    目录 正文 @ts-ignore 和 @ts-expect-error @ts-check 和 @ts-nocheck 正文 单行注释应该在项目里用的很少吧, 我没见过在项目中使用过, 但是了解一下又不吃亏! 那么一起来看看吧!这里开启了TypeScript提示器. 这里谈谈我对它的理解,也可以看看林不渡的TypeScript小册 一般单行注释是以@ts-开头 @ts-ignore 和 @ts-expect-error @ts-ignore 和 @ts-expect-error 仅仅对紧随其后的

  • TypeScript类型断言VS类型守卫示例详解

    目录 类型断言 类型守卫 使用 in 关键字 使用 instanceof 关键字 使用 typeof 关键字 自定义类型守卫 总结 类型断言 类型断言有两种写法,分别为value as Type和<Type>value,它让 TypeScript 编译器将 value 当作 Type 类型.类型断言是一个编译时特性,不进行类型转换,因此不会影响变量在运行时的数据类型.如果某变量是 any 类型,但现在你知道它确切的数据类型,使用类型断言能让 IDE 有代码提示的能力,也能让 TypeScrip

  • Struts2数据输入验证教程详解

    一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我们怎么确定类型转换后的数据,是我们想要的数据呢?这里有点绕.你可以这样想:一个成年男子年龄是18岁,你现在想要得到18这个数据,但是,用户输入32,经过类型转换也是对的,但是数据不是你想要的.这时候,我们要怎么办?所以输入验证在这里就有用处了. 类型转换和输入验证的关系是:类型转换是输入验证的前提,

  • laravel 数据验证规则详解

    如下所示: return [ 'accepted' => '必须为yes,on,1,true', 'active_url' => '是否是一个合法的url,基于PHP的checkdnsrr函数,因此也可以用来验证邮箱地址是否存在', 'after:date' => '验证字段必须是给定日期后的值,比如required|date|after:tomorrow,通过PHP函数strtotime来验证', 'after_or_equal:date' => '大于等于', 'alpha'

  • django Model层常用验证器及自定义验证器详解

    在Django中,对数据进行校验有两种方式:一种是通过Form校验,一种是通过Model校验.在此,我对Model中的校验方法做下记录. 示例之前补充以下几点: 1.Django数据校验方式分为以下三步: Model.clean_fields() 验证字段基本规则比如长度格式等: Model.clean() 可自定义验证条件和报错信息: Model.validate_unique() 为验证添加的唯一性约束. 2.此三步验证通过调用full_claen(exclude=None, validat

  • Linux 远程管理及sshd服务验证知识点详解

    一.SSH远程管理 SSH定义 SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录.远程复制等功能. SSH协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令.因此SSH协议具有很好的安全性. SSH优点 数据传输是加密的,可以防止信息泄漏 数据传输是压缩的,可以提高传输速度 SSH配置文件 sshd 服务的默认配置文件是/etc/ssh/sshd_config ssh_config和sshd_config都是ssh服务器的配置文件 二者区

  • Java JWT实现跨域身份验证方法详解

    目录 1.JWT简介 2.JWT的结构 2.1 头部(header) 2.2 载荷(payload) 2.3 签证(signature) 3.JWT的原则 4.JWT的用法 5.JWT的问题和趋势 6.整合JWT令牌 6.1 在模块中添加jwt工具依赖 6.2 创建JWT工具类 1.JWT简介 JWT(JSON Web Token)是目前流行的跨域认证解决方案,是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信

  • 数据结构TypeScript之二叉查找树实现详解

    目录 树的结构特点 面向对象方法封装二叉查找树(迭代版) 二叉查找树的定义 构造函数 基本单元:二叉查找树节点 主体:二叉查找树 增加节点 查找节点 删除节点 二叉树的遍历 树的结构特点 树是一种有层次的数据结构,通常用于存储具有层次性的数据.比如上下级的关系图,动物的分类图等.树的类型分好几种,无序树.有序树和二叉树等等.但最常应用的还是二叉树,其特点为每个节点最多含有两个子树. 尝试手动构建一颗二叉树. 过程如下: class BinaryTreeNode { constructor(ele

随机推荐