フロントエンド開発といえば。
react アプリの初期化( npm init vite@latest <アプリ名> )

zodで userName の値が正しい場合に、ユニークであるかをさらに検証する

● zodで userName の値が正しい場合に、ユニークであるかをさらに検証する

src/PATH/TO/YOUR/COMPONENT/validations/userNameSchema.ts

import { z } from "zod"
import debounce from "lodash/debounce"

/**
 * ユーザー名がユニークかどうかを検証する
 */
const isUserNameUnique = async (userName: string): Promise<boolean> => {
  // TODO: 実際の検証ロジックを書くこと
  console.log(`● isUserNameUnique (${userName})`)
  await new Promise((resolve) => setTimeout(resolve, 500))

  return userName === "aaaaa" ? false : true
}

/**
 * ユーザー名がユニークかどうかを検証する(debounced)
 */
const debouncedIsUserNameUnique = debounce(isUserNameUnique, 500)

/**
 * userName 入力時に検証するスキーマ
 */
const inputValidationSchema = z
  .string()
  .min(5, { message: "ユーザー名は最低5文字必要です。" })
  .max(15, { message: "ユーザー名は最大15文字です。" })
  .refine((userName) => /^[A-Za-z0-9_]+$/.test(userName), {
    message: "ユーザー名には文字、数字、アンダースコア(_)のみ使用できます。",
  })

export const userNameSchema = z.object({
  userName: inputValidationSchema.refine(
    async (userName) => {
      // 「ユーザー名がユニークかどうかの検証」前のバリデーションでエラーがある場合は true を返して中断してこのバリデーションエラーは表示させない
      const result = inputValidationSchema.safeParse(userName)
      if (!result.success) return true

      // ユーザー名がユニークかどうかを検証する
      const isUnique = await debouncedIsUserNameUnique(userName)
      return isUnique ? true : false
    },
    {
      message: "このユーザー名は既に使用されています。",
    },
  ),
})


export type UserNameSchema = z.infer<typeof userNameSchema>

コンポーネントでは特別に処理を書く必要はありません

MyComponent.tsx

  // react-hook-form
  const formOptions = {
    resolver: zodResolver(userNameSchema),
  }
  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm<UserNameSchema>(formOptions)

  const onSubmit: SubmitHandler<UserNameSchema> = (data) => {
    console.log(data)
  }
No.2432
12/23 17:43

edit