typescript zod:将字符串转换为数字后设置最小值和最大值

nkoocmlb  于 2023-01-06  发布在  TypeScript
关注(0)|答案(2)|浏览(211)

我有数字或数字字符串,我想将其转换为数字并继续通过.min().max()验证,但它没有按预期工作

const numberValid = z.number().or(z.string().regex(/^\d+$/).transform(Number));

const positiveNumber = numberValid.min(0); // method don't exist
0sgqnhkj

0sgqnhkj1#

问题是transform将返回一个z.ZodEffect,它有做进一步转换的方法,但是已经忘记了它最初是z.string的事实。来自z.numbermin方法是不可访问的,因为外部类型将是z.ZodUnion,它也不知道min的改进。
我认为,要获得你所寻找的行为,我可能会采取这样的方法:

const thing = z
  .number()
  .or(z.string().regex(/\d+/).transform(Number))
  .refine((n) => n >= 0);

这是公认的有点缺乏光泽,因为我们不能依赖于min的简化语法和更好的错误,你可以通过添加一个{ message: 'value was less than 0' }作为refine的第二个参数来解决后一个问题。

编辑

这引起了一些关注,我意识到还有另一种方法可以做到这一点。在将值传递给z.number之前,您可以使用preprocess来处理字符串。如果您这样做,您仍然可以使用.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),
)
n53p2ov0

n53p2ov02#

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

相关问题