Oteto Blogのロゴ

Zodで画像FileのMIMEタイプとサイズのバリデーションをする

File (画像) のアップロード時に、zodでMIMEタイプとサイズのバリデーションを行いたい。

type Success = {
  success: true;
};
type Failure = {
  success: false;
  message: string;
};
type Result = Success | Failure;

const ACCEPT_MIME_TYPES = ['image/png', 'image/jpeg', 'image/webp'];
const MAX_MB = 2;
const MAX_SIZE = 1024 * 1024 * MAX_MB;

function validateImg({ type, size }: File): Result {
  if (!ACCEPT_MIME_TYPES.includes(type)) {
    return {
      success: false,
      message: 'PNG・JPEG・WEBP以外の画像はアップロードできません',
    };
  }
  if (size >= MAX_SIZE) {
    return {
      success: false,
      message: `${MAX_MB}MB以上のファイルはアップロードできません`,
    };
  }

  return { success: true };
}
const schema = z.object({
  file: z.instanceof(File).refine((f) => validateImg(f).success),
});

もしエラー毎にmessageを設定したい場合は下記のようにrefine()内で直接判定するのが楽そう。

const schema = z.object({
  file: z
    .instanceof(File)
    .refine(({ type }) => ACCEPT_MIME_TYPES.includes(type), {
      message: 'PNG・JPEG・WEBP以外の画像はアップロードできません',
    })
    .refine(({ size }) => size <= MAX_SIZE, {
      message: `${MAX_MB}MB以上のファイルはアップロードできません`,
    }),
});