zod论坛怎么样_zod论坛怎么修改host
不要信任你的后端zod 是什么?官网上的解释说:Zod 是一个以 TypeScript 为首的模式声明和验证库。我使用术语 "sche
不要信任你的后端zod 是什么?官网上的解释说:Zod 是一个以 TypeScript 为首的模式声明和验证库我使用术语 "schema" 来广义地指任何数据类型,从简单的 字符串 到复杂的嵌套对象第一次使用 zod 是因为 trpc 在官网中介绍通过 zod 来进行接口校验。
对于用惯了 TypeScript 的人来说,第一反应应该是:我都有 TypeScript 了,为什么还要一个库来做校验?举一个例子,我们有一个名为 /api/get-product 的接口,使用 fetch 来获取:
javascript复制代码fetch(/api/get-product).then(res => res.json()).then((res) => { // res 被推断为 any })这里的 res 被推断为 any,因为 res 是运行时产生的, TypeScript 并不知道 res 是什么。
我们当然可以为它补全类型声明,比如:typescript复制代码type Product = { detail: { name: string; price: number
; }; } // 为 res 加上类型声明 fetch(/api/get-product).then(res => res.json()).then((res: Product) => {
console.log(res.detail.price.toFixed(2)) // })这段代码看似没什么问题,但在现实世界中,提供接口的人可能和前端是两个团队,如果有一天,你的后端团队突然把类型改了,
price 改成了字符串类型,你的代码会怎么样呢?Boom!TypeError: res.detail.price.toFixed is not a function你收到了一个运行时报错!用可选链进行防御式编程?
TypeScript 最终还是会被编译成为 javascript,它只能进行编译时检查,运行时的报错它就无能为力了经过上面的问题,你开始不信任后端,我们来进行防御式编程!有一招很好用的方法叫做可选链,比如这样:。
javascript复制代码fetch(/api/get-product).then(res => res.json()).then((res: Product) => { console.log(res?.detail?.price?.toFixed(
2)) // 可行吗? })可选链可以避免某些字段为空,但是当字段类型改变时,显得有些无能为力正确的做法是,把 res 的类型声明为 unknown,然后依照 TypeScript 的报错做严格的类型检查,比如这样:。
js复制代码fetch(/api/get-product).then(res => res.json()).then((res: unknown) => { if (typeof res ===
object && res !== null && detailin res) { if (typeof res.detail === object && res.detail !== null
&& pricein res.detail) { if (typeof res.detail.price === number) { console.log(res.detail.price.toFixed(
2)) } } } })看起来很健壮了,但是这段代码实在是又臭又长!zod 就是用来解决这种场景,让我使用 zod 来进行运行时校验!使用 zod 进行接口校验zod 使用 schema 来定义验证规则,我们创建一个 schema 来表示上面的接口:
ts复制代码const productSchema = z.object({ detail: z.object({ name: z.string(), price: z.number(), }) })
通过工具方法 infer 可以将 schema 转化为 TypeScript 类型声明:ts 复制代码typeProduct = z.infer使用 parse 方法来进行校验,我们改写上面的代码:
ts复制代码fetch(/api/get-product).then(res => res.json()).then((res) => { const product = productSchema.parse(res)
console.log(product.detail.price.toFixed(2)) // })如果类型不匹配,这个时候 zod 会报错,比起上面的 TypeError: res.detail.price.toFixed is not a function
,zod 的报错会更明确:... Expected number, received string如果在遇到异常时不想中断代码,可以用 safeParse做更精细的流程控制:ts复制代码 fetch(
/api/get-product).then(res => res.json()).then((res) => { const product = productSchema.safeParse(res)
if (product.success) { console.log(product.data.detail.name) console.log(product.data.detail.price) }
else { console.error(product.error) } })代码优雅了很多!以上是 zod 最常用的 API,除了接口校验,让我们看看还有哪些场景适合用到 zod。
表单校验表单校验也是使用 zod 的主要场景,用户的输入需要在运行时进行检查,zod 内置了一些方法可以对数据进行更精细的校验,比如:email: 邮箱校验;min / max: 校验最大最小值;message: 使用验证方法时,你可以传递一个附加参数,以提供自定义错误信息;
refine: 自定义验证函数,做精细化控制比如下面登录相关的 schema:css复制代码const signUpSchema = z.object({ email: z.string().email(), password: z.。
string().min(6, Password must be at least 6 characters), confirmPassword: z.string(), }).refine(data => data.password === data.confirmPassword, { message:
Passwords do not match, path: [confirmPassword], })这段代码的描述了这样的校验规则:signUpSchema 定义了一个对象,该对象包含三个属性:email,password 和 confirmPassword。
email:字符串,并且必须是一个有效的电子邮件地址;password:字符串,但是它必须至少包含6个字符如果密码长度小于6个字符,将返回错误消息Password must be at least 6 characters;。
confirmPassword:字符串;refine 方法用于添加一个自定义验证确保 password 和 confirmPassword 两个字段的值是相同的如果这两个字段的值不匹配,将返回错误消息 Passwords do not match,并指出错误发生在confirmPassword 字段。
URL 和 ENV 校验URL 和 ENV 和上面的例子很类似,一个区别是,URL 和 ENV 在默认情况下是字符串,zod 提供了一种方便的方法 zod.coerce 来强制转换原始类型,比如如下 ENV schema:
ts复制代码const EnvSchema = z.object({ NODE_ENV: z.enum([development, production]), PORT: z.coerce.number(), HOST: z.
string(), }) type Env = z.infer这里的 PORT 被转换为了 number包体积太大?试试 valibot以上介绍了 zod 的大部分使用场景。
有一问题是,zod 的官网介绍 zod 是一个小巧的库,大概 8kb但是,一般情况下你也用不着 zod 的全部特性,引入一个 8kb 的库是值得的吗?如果你特别在意包体积的话,或许可以试试 valibot?。
看看 valibot 对自己的介绍:Valibot 的功能与 zod 非常相似最大的区别是我们的API的 模块化设计 以及通过 tree-shaking 和代码分割将捆绑尺寸降低到最小的能力根据模式,Valibot可以将捆绑尺寸降低到。
95%,而与ZOD相比特别是对于客户端验证表单,这可能是一个很大的优势我们改写上面的表单校验:ts复制代码import * as v fromvalibot; const Schema = v.object
({ email: v.string([v.email()]), password: v.string([v.minLength(6, Password must be at least 6 characters
)]), confirmPassword: v.string(), }, [v.custom(({ password, confirmPassword }) => password === confirmPassword,
Passwords do not match)]); const result = v.parse(Schema, { email: jane@example.com, password: 12345678
, confirmPassword: 12345678, }); console.log(result);你可以将这段代码贴在 playground 中验证从 api 设计上来讲,valibot 使用了按需引入的 api 设计模型,所以能做到使用 tree-shaking 降低代码的包体积。
你更喜欢哪一种 api 设计呢?感谢阅读本文,欢迎讨论~
- 标签:
- 编辑:李松一
- 相关文章
-
杜桥东部人才网怎么样_杜桥东部人才网官网
其中地下线长度17.833km,山岭隧道长度4.985km,高架线长度29.221km,路基长度0.357km。
-
997788中国收藏热线怎么样_997788中国收藏热线官网
再说瓷器:我有一个好朋友,他收集瓷器近40年,它的瓷器的种类和数量,比北京大瓷器商铺的瓷器都多,他有宋代的”执壶“,明清的青花瓷,有八大…
- ckdvd怎么样_晚秋影视大全在线观看
- 快猫最新官网怎么样_快连最新官网
- 52cake怎么样_52cake蛋糕网
- 爱看小说网怎么样_苏渊林初墨小说免费阅读爱看小说网
- 999听书网怎么样_喜马拉雅听书免费版