Zod:继 Typescript 之后的下一个热门
内容
介绍
我最近偶然发现了一个名为 Zod 的小图书馆。
我浏览文档的第一反应是这看起来很有趣。
直到我尝试了之后,我才感觉到差异——差异是巨大的。
没有什么能与之相比。
这是一种不同的方法,但一旦你尝试了 Zod,我想你就会明白我的意思。
在我看来,Zod 的方法在 Typescript 中进行数据验证时在健壮代码和开发人员体验 (DX) 之间取得了适当的平衡。
⚠️ 免责声明:阅读本文后,您可能不想使用任何其他验证库!(已警告)
理解原因
Typescript 通过静态检查代码是否符合类型中定义的“契约”来在开发过程中引入出色的检查。
这在大多数情况下都有效,但是在生产中,它会变得更加复杂。
-
Javascript - Typescript 不在生产环境中运行,它会编译为 Javascript
-
松散的契约——当代码编译为 JavaScript 时,TypeScript 类型契约不会被强制执行
-
数据可预测性——在生产运行的复杂系统中,数据质量和来源往往是不可预测的
因此,出于这个原因,需要运行时验证来在 Javascript 中强制执行这些契约。
管理合同
当我们使用 Javascript 中的函数时,它由输入和输出组成。
一组特定的输入会给你一组特定的输出——这就是我所说的合同。
这与您与银行、保险公司或电信公司签订的合同没有太大区别。
当您签约他们的服务时,会获得一定程度的保证。
通过建立合同,它迫使我们缩小输入和输出的范围。
本质上,您减少了表面积,从而使功能更加可预测。
现在的问题是,如何在 Javascript 中实现这一点?
传统方法
实现此目的的传统方法是安装某种验证库(即 Joi、Ajv 等)。
最常见的应用是使用用户输入数据管理表单输入。
但是,它不一定只适用于表单,您可以对任何内容使用运行时验证。
它将使您的代码更加健壮,因为任何不符合合同的数据都将被视为失败。
没有中间或边缘情况。这使得代码非常严格。
这些库的缺点是存在大量重复 -就像大型代码库中的大量重复一样。
您不仅需要定义 Typescript 类型,还必须定义验证模式。
谈论加倍工作......
如果你曾经需要这样做,你就会明白其中的痛苦。而且,我们甚至不必讨论这会给代码库带来多大的膨胀😵。
然后你知道的下一件事就是你开始这样做👇
那么,还有更好的办法吗?
如果我告诉你有...
你大概能猜到。我给你个提示,它以 Z 开头。
佐德之路
输入佐德。
这就是 Zod 与所有其他验证库的不同之处。
它与其他东西有什么不同?Zod 采用的是模式优先的方法。
意思是,您从验证模式(Zod 模式)开始。
然后,这个 Zod 模式将成为您的验证和类型。
因此,您可以获得两全其美的结果!
您不仅可以从模式中获得运行时验证,还可以通过将模式转换为 Typescript 来获取类型。
很棒吧?说说超级充电效率和开发者体验😍⚡️
简单示例
插图已经够多了,我想看一些代码!
让我们来看一个简单的例子。
假设我们是一家披萨店,我们需要为我们的网站设计一些模式。
1. 定义 Zod 模式
import { z } from 'zod';
// Zod schema
const pizzaSchema = z.object({
sauce: z.string(),
ingredients: z.array(z.string()),
});
- 将 Zod 模式转换为 Typescript 类型
import { z } from 'zod';
// Zod schema
const pizzaSchema = z.object({
sauce: z.string(),
ingredients: z.array(z.string()),
});
// TypeScript type
export type IPizza = z.infer<typeof pizzaSchema>;
- 制作一些披萨
import { z } from 'zod';
// Zod schema
const pizzaSchema = z.object({
sauce: z.string(),
ingredients: z.array(z.string()),
});
// TypeScript type
export type IPizza = z.infer<typeof pizzaSchema>;
const pepperoniPizza: IPizza = {
sauce: 'tomato',
ingredients: [
'cheese',
'pepperoni',
],
};
console.log(pepperoniPizza);
// => { sauce: 'tomato', ingredients: [ 'cheese', 'pepperoni' ] }
const hawaiianPizza: IPizza = {
sauce: 'tomato',
ingredients: [
'cheese',
'pineapple',
'ham',
],
};
console.log(hawaiianPizza);
// => { sauce: 'tomato', ingredients: [ 'cheese', 'pineapple', 'ham' ] }
- 运行时验证
import { z } from 'zod';
// Zod schema
const pizzaSchema = z.object({
sauce: z.string(),
ingredients: z.array(z.string()),
});
// TypeScript type
export type IPizza = z.infer<typeof pizzaSchema>;
const pepperoniPizza: IPizza = {
sauce: 'tomato',
ingredients: [
'cheese',
'pepperoni',
],
};
console.log(pizzaSchema.parse(pepperoniPizza));
// => { sauce: 'tomato', ingredients: [ 'cheese', 'pepperoni' ] }
const hawaiianPizza: IPizza = {
sauce: 'tomato',
ingredients: [
'cheese',
'pineapple',
'ham',
],
};
console.log(pizzaSchema.parse(hawaiianPizza));
// => { sauce: 'tomato', ingredients: [ 'cheese', 'pineapple', 'ham' ] }
console.log(pizzaSchema.parse(null)); // throws ZodError
取得适当的平衡
大多数库都会通过牺牲开发人员体验(DX)来强迫您做正确的事情。
但佐德的情况并非如此,团队确实做得“恰到好处”。
使用 Zod 时,您可以毫无阻碍地做正确的事情。
它与 Typescript 无缝协作。
这是一个值得研究的工具。
建立新标准——端到端类型安全
Zod 为 tRPC 等有趣的工具打开了大门,将开发人员体验 (DX) 提升到一个新的水平。
tRPC 的主要思想是您可以使用模式定义后端端点,然后在客户端自动完成。
这提高了所有其他框架提供与 tRPC 集成或创建“类似”体验的标准。
我认为 tRPC 和“类似 tRPC 的体验”在未来会更加流行,仅仅因为它提供的开发速度和开发人员体验 (DX)。
结论
好了,你看,这就是佐德。
该库为您提供使用运行时(模式)和静态(类型)验证来设计健壮代码的无缝体验。
在我们结束之前,让我们先回顾一下。
并且...目前就这些了,请继续关注更多内容!
如果您发现这篇文章有用或者学到了新的东西,请与朋友或同事分享这篇文章🙏❤️(谢谢!)
也发表于 - jerrychang.ca
⚠️ 注意: Yup 还支持根据定义的数据模式推断类型。您可以使用类似yup.InferType的方法来获取 Typescript 类型。它只是另一个很棒的库,可以让你实现与 Zod 类似的功能。文章来源:https://dev.to/jareechang/zod-the-next-biggest-thing-after-typescript-4phh