我有数字或数字字符串,我想将其转换为数字并继续通过 验证它.min() .max(),但它没有按我的预期工作
const numberValid = z.number().or(z.string().regex(/^\d+$/).transform(Number));
const positiveNumber = numberValid.min(0); // method don't exist
Run Code Online (Sandbox Code Playgroud)
Sim*_*ens 19
从 version 开始,您可以像这样3.20使用:z.coerce.number()
const numberValid = z.coerce.number().min(0)
numberValid.parse(123) // OK
numberValid.parse(-123) // ERROR
numberValid.parse("123") // OK
numberValid.parse("-123") // ERROR
Run Code Online (Sandbox Code Playgroud)
Sou*_*man 16
问题是transform将会返回 a z.ZodEffect,它具有进行进一步转换的方法,但已经忘记了它最初是 的事实z.string。minfrom 的方法不可z.number访问,因为外部类型z.ZodUnion也不知道min细化。
我认为要获得您正在寻找的行为,我可能会采取以下方法:
const thing = z
.number()
.or(z.string().regex(/\d+/).transform(Number))
.refine((n) => n >= 0);
Run Code Online (Sandbox Code Playgroud)
诚然,这有点缺乏光泽,因为我们不能依赖min它简化的语法和更好的错误。{ message: 'value was less than 0' }您可以通过添加 a作为第二个参数来解决后一个问题refine。
这引起了一些关注,我意识到还有另一种方法可以做到这一点。您可以preprocess在将值传递给 之前使用 来处理字符串z.number。如果你这样做,你仍然可以利用.min所有好的错误消息和东西。
const numberValid2 = z.preprocess(
(input) => {
const processed = z.string().regex(/^\d+$/).transform(Number).safeParse(input);
return processed.success ? processed.data : input;
},
z.number().min(0),
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21956 次 |
| 最近记录: |