typescript Joi.ref()在Zod中等价于对象文字验证

7fyelxc5  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(167)

我的任务是将代码库从使用Joi转换为使用Zod进行TypeScript验证。在这个过程中,我遇到了一个障碍,即在zod库中找到与joi.ref()等效的方法。

const joiParentObject = joi.object({
    someKey: joi.string().required()
})

const joiChildObject = joiParentObject.keys({
    someChildKey: joi.string().default(joi.ref('someKey'))
})

const zodParentObject = z.object({
    someKey: z.string()
})

const zodChildObject = z.object({
    someChildKey: z.string().... <---- here
}).merge(zodParentObject)

我尝试过使用不同的对象文字方法,比如function someChildKey() {...}get someChildKey(){}set someChildKey(){},但当使用this.访问父对象的同级键时,它们都以object is possibly undefined结束。

mefy6pfw

mefy6pfw1#

换句话说,您希望someChildKey是可选的(即string | undefined),如果它是undefined,你希望它的值是someKey
Zod has a .default() method,你可以传递一个默认值或一个函数,它的计算结果是默认值,但你不能访问函数中的对象的其他属性。所以在这种情况下,.default()方法不能使用(但我提到它是因为它在更简单的情况下很有用)。
一种解决方案是使用Zod's .optional() methodsomeChildKey标记为可选,并在使用Zod's .transform() method解析后为其设置默认值:

import { z } from 'zod'

const parentObject = z.object({
  someKey: z.string(),
})

const childObject = z
  .object({
    someChildKey: z.string().optional(),
  })
  .merge(parentObject)
  .transform((data) => ({
    ...data,
    someChildKey: data.someChildKey ?? data.someKey,
  }))

.transform()中,data参数是整个对象,所以data.someKeyJoi.ref('someKey')有点相同。
顺便说一下,Joi的object.keys()方法似乎禁止未定义的键。对于类似的效果,您可以使用Zod's .strict() method

相关问题