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

aiazj4mn  于 2023-05-23  发布在  TypeScript
关注(0)|答案(1)|浏览(123)

假设你在佐德有一个类似这样的基本系统:

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)
})

如何遍历属性并检查属性上的选项?
我看到有一个.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
    }
  }
}

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

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

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

osh3o9ms

osh3o9ms1#

Zod并不是真的这样使用的,但是根据你的模式的复杂性,你可以通过查看源代码走得很远:https://github.com/colinhacks/zod/blob/master/src/types.ts
例如,您可以看到各种类型都是类,例如数字类型有minValuemaxValue getter。为了得到这些,你可以这样做:

if (s instanceof ZodNumber)
  console.log(s.minValue, s.maxValue)

你提到的shapeZodObject类型的getter,这意味着你可以:

if (s instanceof ZodObject)
  for (const field of schema.shape)
    // look at each field

你还会发现可选和可空模式是类ZodOptionalZodNullable,它们都有一个unwrap()方法来查看内部值,这意味着你可以这样做:

let required = true;

while (s instanceof ZodOptional || s instanceof ZodNullable) {
  required = false;
  s = s.unwrap();
}

如果你做了细化或转换,它们将被 Package 在ZodEffects类中,在那里你会看到有一个innerType()方法来获取内部类型。
基本上,你只需要递归地循环遍历事物,查看每一件事物,看看它是什么类型,然后根据需要处理它。

相关问题