🧩

[React-Hook-Form] yupのtips [yup]

2023/04/21に公開

yup を使う機会があったのでメモ

schema から型を生成する

const schema = yup.object({
  name: yup.string().required(),
  gender: yup
    .string()
    .required()
    .oneOf(["male", "female", "other"] as const),
});
interface User extends yup.InferType<typeof schema> {}
// または
type User = yup.InferType<typeof schema>;

{
  name: string;
  gender: string;
}

入力した値によってバリデーションを変えたいとき

例 : 性別が男性の場合のみ住所の入力を必須にする

  • when()を使う
const schema = yup.object({
  name: yup.string().required(),
  gender: yup.string().required().oneOf(["male", "female", "other"]),
  address: yup.string().when("gender", {
    is: "male",
    then: yup.string().required(),
  }),
});
  • test()を使う
const schema = yup.object({
  name: yup.string().required(),
  gender: yup.string().required().oneOf(["male", "female", "other"]),
  address: yup.string().test("NO_ADDRESS", "住所を入力してください", function (value) {
    if (this.parent.gender !== "male") {
      //男性以外は住所入力は任意なのでテストをパスする
      return true;
    }
    //入力があればテストパス、入力がない場合は場合はエラー表示
    return !!value;
  }),
});

schema に引数を渡して動的に作成したいとき

  • 関数にして引数を受け取り、schema を返す

例) ペットを飼っている人のみ住所の入力を必須にする

const createSchema = (pets?: { name: string }[]) => {
  return yup.object({
    name: yup.string().required(),
    address: yup.string().test("NO_ADDRESS", "住所を入力してください", function (value) {
      //ペットを飼っていない人はテストをパス
      if (!pets) {
        return true;
      }
      //入力があればテストパス、ない場合はエラーをを表示
      return !!value;
    }),
  });
};

配列の型を指定する

statuses1 → バリデーションは機能するがnumber[]
statuses2 → バリデーションを機能させつつStatus[]

status は適当です

//0: 下書き 1: 作成済 2: エラー
type Status = 0 | 1 | 2;
const statuses: Status[] = [0, 1, 2];

const sampleSchema = object({
  statuses1: array().of(number().required().oneOf(statuses)).required(),
  statuses2: array().of(mixed<Status>().oneOf(statuses).required()).required(),
});
type SampleFormData = InferType<typeof sampleSchema>;
type SampleFormData = {
  statuses1: number[];
  statuses2: Status[];
};

参考

Discussion