typescript 带判别并的Zod递归类型

jgwigjjp  于 2023-02-20  发布在  TypeScript
关注(0)|答案(1)|浏览(117)

如何将这个递归的判别并集转换为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的错误,它不起作用。

k2fxgqgv

k2fxgqgv1#

这里的关键是使用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)

相关问题