如何让 zod 将输入读取为数字而不是文本

Zac*_*ipp 9 forms typescript reactjs zod

我正在尝试输入一个应该接受特定范围内的数字的输入。当我提交时,zod 说它需要一个数字,但得到一个字符串。

import {z} from "zod"
import { fromZodError } from "zod-validation-error";

//give this file it's own unique name to identify the form it uses
export const creditCardData = z.object({
    //------name------
    firstName: z.string().min(3, 'Min Length must be 3').max(10, 'Max Length must be 10'),
    age: z.number().min(1).max(99).int()
})

export const defaultCardData={
    firstName:'',
    age: 0
}

export type CardData = z.infer<typeof creditCardData>

//form submit function
export const handleSubmit = (
event: React.FormEvent<HTMLFormElement>,
submission: CardData,
isError: (val: boolean) => void,
isLoading: (val: boolean) => void
) => {
    event.preventDefault();

    isLoading(true)
    const results = creditCardData.safeParse(submission);
    if (!results.success) {
        const errorType = fromZodError(results.error);
        console.log(errorType.message);
        isLoading(false)
        isError(true)

    } else {
    isError(false)
    isLoading(false)
    //put api call
    console.log(results.data);
}
};
Run Code Online (Sandbox Code Playgroud)

这是我进行验证的 zod 文件

import { useState } from "react";
import { CardData, defaultCardData, handleSubmit } from "./validation/zod";
import Input from "./components/Input";

function App() {
  //state date for form
  const [data, setData] = useState<CardData>(defaultCardData);
  //loading and function
  const [loading, setLoading] = useState(false);
  const isLoading = (val: boolean) => setLoading(val);
  //error and function
  const [error, setError] = useState(false);
  const isError = (val: boolean) => setError(val);

  return (
    <main className="min-h-screen flex justify-center flex-col items-center text-white">
      <h1 className="text-2xl font-bold ">Card Data</h1>

      <form
        className="text-black"
        onSubmit={(event) => handleSubmit(event, data, isError, isLoading)}
      >
        {/* //first name */}
        <Input
          label="First Name "
          id="firstName"
          value={data.firstName}
          handleChange={(e: { target: { value: string } }) => {
            setData({ ...data, firstName: e.target.value });
          }}
        />
        {/* //age */}
        <Input
          label="Age "
          id="age"
          value={data.age}
          type="number"
          handleChange={(e: { target: { value: number } }) => {
            setData({ ...data, age: e.target.value });
          }}
        />
        {/* //submit */}
        <button
          className="block mt-4 p-2 bg-white border-black border-2 rounded-md"
          type="submit"
        >
          Submit
        </button>
        {loading && <p>Loading...</p>}
        {error && <p>Error on submission</p>}
      </form>
    </main>
  );
}

export default App;

Run Code Online (Sandbox Code Playgroud)

这是我有用户输入的部分。当我提交时,我收到错误“验证错误:预期数字,在“年龄”收到字符串。”

小智 17

根据 Zod 文档,Zod 现在提供了一种更方便的方法来强制原始值。

age: z.coerce.number().gte(18, 'Must be 18 and above');
Run Code Online (Sandbox Code Playgroud)


Avi*_*vik 4

您可以使用预处理。例如

age : z.preprocess((a) => parseInt(z.string().parse(a),10),
z.number().gte(18, 'Must be 18 and above'))
Run Code Online (Sandbox Code Playgroud)