Zod Schema:如何使字段可选或具有最小字符串约束?

问题描述 投票:0回答:4

我有一个字段,我希望该值是可选的,或者该字段的最小长度为

4

我尝试过以下方法:

export const SocialsSchema = z.object({
  myField: z.optional(z.string().min(4, "Please enter a valid value")),
});

如果我使用如下值,则此方法会通过:

"good"
,但如果我有一个空值,则会失败。

如果值不为空,如何使用 zod 模式正确实现约束以创建具有最小约束的可选值?

是否可以在不使用正则表达式或正则表达式解决方案的情况下做到这一点?

javascript typescript schema zod
4个回答
24
投票

在您的情况下,您认为

""
undefined
相同(即:当字符串为空时,就像根本没有字符串一样)。

在 Zod 中可以这样实现:

import { z } from "zod";
import { strict as assert } from "node:assert";

// `myString` is a string that can be either optional (undefined or missing),
// empty, or min 4
const myString = z
  .union([z.string().length(0), z.string().min(4)])
  .optional()
  .transform(e => e === "" ? undefined : e);

const schema = z.object({ test: myString });

assert( schema.parse({}).test === undefined ); // missing string
assert( schema.parse({ test: undefined }).test === undefined ); // string is undefined
assert( schema.parse({ test: "" }).test === undefined ); // string is empty
assert( schema.parse({ test: "1234" }).test === "1234" ); // string is min 4

// these successfully fail
assert( schema.safeParse({ test: "123" }).success !== true );
assert( schema.safeParse({ test: 3.14 }).success !== true );

17
投票

基于此 Github 问题及其答案

or
选项与可选和文字结合使用,如下所示。

export const SocialsSchema = z.object({
  myField: z
    .string()
    .min(4, "Please enter a valid value")
    .optional()
    .or(z.literal('')),
});

5
投票

你在这里:

import { z } from "zod";

export const SocialsSchema = z.object({
  myField: z.string().min(4, "Please enter a valid value").optional()
});
// ok
console.log(SocialsSchema.parse({ myField: undefined }));

// ok
console.log(SocialsSchema.parse({ myField: "1234" }));

// ok
console.log(SocialsSchema.parse({ myField: "" }));

// throws min error
console.log(SocialsSchema.parse({ myField: "123" }));

0
投票

当前最佳答案很好,但有一个缺陷。与约束不匹配的字符串的 Zod 错误消息将来自

z.string().length(0)
,而不是
z.string().min(4)

通过反转并集的顺序,错误的优先级将被纠正。

import { z } from "zod";

// `myString` is a string that can be either optional (undefined or missing),
// empty, or min 4
const myString = z
  .union([z.string().min(4), z.string().length(0)])
  .optional()
  .transform(e => e === "" ? undefined : e);

© www.soinside.com 2019 - 2024. All rights reserved.