NextJs中Yup验证可选文件输入:数组与单个File类型适配问题
更优实现方案
1. Schema层适配参数类型(不修改工具函数)
直接在Yup的test回调中,把单个File包装成数组后传给原有校验函数,工具函数的类型定义无需改动:
medicalConcernDocument: yup .mixed<File>() .nullable() .test( 'check-file-size', `File size cannot exceed ${maxFileSizeInMB}MB`, (value) => checkFileSize(value ? [value] : null) ) .test( 'check-file-type', `File is unsupported, supported files: ${supportedFileTypeMessage}`, (value) => checkFileType(value ? [value] : null) )
这种方式保持工具函数的专一性,仅在Schema层处理输入差异,逻辑边界清晰。
2. 重构校验函数,兼容多输入类型
修改工具函数的参数类型,使其同时支持单个File和File数组,内部自动处理输入格式:
export function checkFileSize(fileOrFiles: File | File[] | null | undefined): boolean { // 统一处理:数组取getFile结果,单个File直接用 const file = Array.isArray(fileOrFiles) ? getFile(fileOrFiles) : fileOrFiles; if (!file) { return true; } const fileSizeInBytes = file.size; const fileSizeInMB = Math.round(fileSizeInBytes / 1024 / 1024); return fileSizeInMB <= maxFileSizeInMB; } export function checkFileType(fileOrFiles: File | File[] | null | undefined): boolean { const file = Array.isArray(fileOrFiles) ? getFile(fileOrFiles) : fileOrFiles; if (!file) { return true; } return supportedFileTypes.includes(file.type); }
这种方式让校验函数更通用,无论传入单个文件还是数组都能正常工作,Schema层无需额外适配。
3. 用Yup的transform统一字段类型
在Schema中先将输入的File数组转换为单个File(取数组第一个元素),再执行校验逻辑:
medicalConcernDocument: yup .mixed<File>() .nullable() .transform((value) => { // 数组转单个File,空数组返回null return Array.isArray(value) ? value[0] ?? null : value; }) .test( 'check-file-size', `File size cannot exceed ${maxFileSizeInMB}MB`, (file) => { if (!file) return true; const fileSizeInMB = Math.round(file.size / 1024 / 1024); return fileSizeInMB <= maxFileSizeInMB; } ) .test( 'check-file-type', `File is unsupported, supported files: ${supportedFileTypeMessage}`, (file) => { if (!file) return true; return supportedFileTypes.includes(file.type); } )
这种方式直接在Schema层统一了字段类型,后续校验逻辑可以直接针对单个File编写,适合不需要复用校验函数的场景。
内容的提问来源于stack exchange,提问作者Robin Dalmy
相关产品推荐
相关产品推荐

