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以上のファイルはアップロードできません`,
}),
});