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

Bar*_*yle 30 javascript schema typescript zod

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

我尝试过以下方法:

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

如果我使用像这样的值,这会通过"good",但如果我有一个空值,那么它会失败。

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

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

Luc*_*ito 36

在您的情况下,您认为""与相同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 );
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这确实有技巧。但是,可能需要将顺序更改为“[z.string().min(4), z.string().length(0)]”,以便“min(4)”的错误消息优先于“长度(0)`。 (4认同)
  • @RobertRendell OP 希望将空字符串“””与“未定义”相同,但对于 Zod 来说,空字符串仍然是有效的非缺失字符串,因此验证有点棘手。 (2认同)

Ilm*_*ula 34

基于这个 Github 问题及其答案

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

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


Rob*_*ell 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" }));
Run Code Online (Sandbox Code Playgroud)