如何在 Zod 中迭代属性并获取类型?

Lan*_*ard 6 typescript zod

假设你在 Zod 中有一个像这样的基本系统:

import { z } from 'zod'

const Post = z.object({
  title: z.string(),
})

const User = z.object({
  name: z.string(),
  email: z.string().optional(),
  posts: z.array(Post),
  loginCount: z.number().min(1)
})
Run Code Online (Sandbox Code Playgroud)

如何迭代属性并检查属性上的选项?

我看到有一个.shape属性,但是如何做到这一点:

for (const name in shape) {
  const prop = shape[name]

  if (prop.min != null) {
    console.log(`Has min ${prop.min}`)
  }
  if (prop.max != null) {
    console.log(`Has max ${prop.max}`);
  }
  if (prop.optional === true) {
    console.log(`Is optional`);
  }
  if (prop.type) {
    if (prop.type is array) {
      prop.type.forEach(item => {
        console.log(`Has array item type ${item.name}`)
      })
    } else if (prop.type is union) {
      // ... show union type names
    } else {
      // show basic type name
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我需要使用这个定义,例如:

  • 获取每个模式的键
  • 获取架构上的属性允许的属性类型(例如,这样我就可以知道要插入哪个数据库表)
  • 制作文档
  • 像这样的东西。

我没有看到任何类似这样的文档,并且不想通过创建自己的库来进行类型和类型检查来重新发明轮子。

Svi*_*ish 9

Zod 并不是真正为这样使用而设计的,但根据模式的复杂性,通过查看源代码您可以走得很远: https: //github.com/colinhacks/zod/blob/master/src/类型.ts

例如,您可以看到各种类型都是类,例如数字类型具有 getterminValuemaxValuegetter。因此,要获得这些,您可以执行以下操作:

if (s instanceof ZodNumber)
  console.log(s.minValue, s.maxValue)
Run Code Online (Sandbox Code Playgroud)

shape提到的是类型的吸气剂ZodObject,这意味着您可以执行以下操作:

if (s instanceof ZodObject)
  for (const field of schema.shape)
    // look at each field
Run Code Online (Sandbox Code Playgroud)

您还会发现可选和可为 null 的模式是类ZodOptionalZodNullable,并且它们都有一个unwrap()方法来查看内部值,这意味着您可以执行以下操作:

let required = true;

while (s instanceof ZodOptional || s instanceof ZodNullable) {
  required = false;
  s = s.unwrap();
}
Run Code Online (Sandbox Code Playgroud)

如果您进行细化或转换,它们将被包装在ZodEffects类中,您将看到有一个innerType()方法可以获取内部类型。

基本上,你只需要递归地循环遍历事物,查看每个事物,看看它是什么类型,然后根据你的需要进行处理。