Express中使用Multer遇到的两个TypeScript错误求助
Express + Multer + Sharp 图片上传的TypeScript错误修复
原始代码
import multer, { FileFilterCallback } from "multer"; import sharp from "sharp"; import { NextFunction, Request, Response } from "express"; const multerStorage = multer.memoryStorage(); const multerFilter = ( req: Request, file: Express.Multer.File, cb: FileFilterCallback ) => { if (file.mimetype.startsWith("image")) { cb(null, true); } else { cb(new Error("Not an image! Please upload only images."), false); } }; const upload = multer({ storage: multerStorage, fileFilter: multerFilter }); export const uploadRecipeImages = upload.array("images", 6); export const resizeRecipeImages = async ( req: Request, res: Response, next: NextFunction ) => { if (!req.files?.images) return next(); req.body.images = []; await Promise.all( req.files.images.map(async (file, index) => { const filename = `recipe-${req.params.id}-${Date.now()}-${ index + 1 }.jpeg`; await sharp(file.buffer) .resize(1024, 1024) .toFormat("jpeg") .jpeg({ quality: 90 }) .toFile(`public/img/recipes/${filename}`); req.body.images.push(filename); }) ); next(); };
错误1:cb(new Error(...), false)类型不兼容
报错信息:Argument of type 'Error' is not assignable to parameter of type 'null'.ts(2345)
修复方案
问题源于FileFilterCallback的类型推断限制,直接显式定义回调参数类型即可解决:
const multerFilter = ( req: Request, file: Express.Multer.File, // 显式指定回调参数类型,替代FileFilterCallback cb: (error: Error | null, acceptFile: boolean) => void ) => { if (file.mimetype.startsWith("image")) { cb(null, true); } else { cb(new Error("Not an image! Please upload only images."), false); } };
错误2:req.files?.images属性不存在
报错信息:Property 'images' does not exist on type '{ [fieldname: string]: File[]; } | File[]'. Property 'images' does not exist on type 'File[]'.ts(2339)
修复方案(二选一)
方案1:适配upload.array的返回格式
upload.array("images", 6)会将上传文件存入req.files数组(类型为File[]),而非req.files.images对象。修改判断逻辑:
export const resizeRecipeImages = async ( req: Request, res: Response, next: NextFunction ) => { // 直接判断req.files是否存在且不为空数组 if (!req.files || req.files.length === 0) return next(); req.body.images = []; await Promise.all( // 遍历req.files数组,而非req.files.images req.files.map(async (file, index) => { const filename = `recipe-${req.params.id}-${Date.now()}-${index + 1}.jpeg`; await sharp(file.buffer) .resize(1024, 1024) .toFormat("jpeg") .jpeg({ quality: 90 }) .toFile(`public/img/recipes/${filename}`); req.body.images.push(filename); }) ); next(); };
方案2:改用upload.fields实现req.files.images格式
如果想保留req.files.images的写法,将upload.array替换为upload.fields,并扩展Express Request类型:
- 修改上传中间件:
// 替换原来的uploadRecipeImages export const uploadRecipeImages = upload.fields([ { name: "images", maxCount: 6 } ]);
- 在项目根目录创建
types/express.d.ts文件,扩展Request类型:
declare global { namespace Express { interface Request { files?: { images?: Express.Multer.File[]; }; } } }
这样req.files?.images的类型就能被TypeScript正确识别。
内容的提问来源于stack exchange,提问作者Mohammad Reza Ghasemi
相关产品推荐
相关产品推荐

