【问题标题】:Zod recursive type with discriminated unionZod 递归类型与可辨别联合
【发布时间】:2023-02-17 06:16:41
【问题描述】:

这个递归的discriminated union如何转化为zod呢?

interface TextInput {
  type: 'text-input'
}

interface Group {
  type: 'group';
  components: AppComponent[]
}

type AppComponent = TextInput | Group

const component: AppComponent = {
  type: 'group',
  components: [{
    type: 'text-input'
  }],
}

zod 版本会是什么样子?

我的尝试:

import { z } from 'zod';

const TextInputSchema = z.object({
    type: z.literal('text-input'),
});

const GroupSchema = z.object({
    type: z.literal('group'),
    components: z.array(ComponentSchema),
});

const ComponentSchema = z.discriminatedUnion('type', [TextInputSchema, GroupSchema]);

但由于[...] type is referenced directly or indirectly in its own initializer 的错误,这不起作用。

【问题讨论】:

标签: typescript zod


【解决方案1】:

这里的关键是使用 z.lazy,它让我们使用尚未完全定义的 zod 类型。

import {z} from "zod"

interface TextInput {
  type: 'text-input'
}

interface Group {
  type: 'group';
  components: AppComponent[]
}

type AppComponent = TextInput | Group

const TextInput = z.object({
  type: z.literal("text-input")
})

const Group: z.ZodType<Group> = z.lazy(() => z.object({
  type: z.literal("group"),
  components: AppComponent.array()
}))

const AppComponent = TextInput.or(Group)

const component = AppComponent.parse({
  type: 'group',
  components: [
    { type: 'text-input' }, 
    { 
      type: "group",
      components: [
        { type: 'text-input' }
      ]
    }
  ],
})

console.log(component)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 2012-11-09
    相关资源
    最近更新 更多