如何编写带默认值的可选对象参数,满足TypeScript与ESLint要求?
问题描述
我定义了如下异步函数resizeImage,第三个参数通过解构赋值设置了width和height的默认值:
const resizeImage = async function resizeImage( buffer: Buffer, name: string, { width = 500, height = 500, ...others }: { width?: number; height?: number } ) { Logger.info('hello from resizeImage'); /** * ## cropping the image */ await sharp(buffer) .resize({ fit: sharp.fit.cover, width, height, ...others, }) /** * ## convert to jpeg */ .toFormat('jpeg') /** * ## set quality */ .jpeg({ quality: 90 }) /** * ## save to file */ .toFile(`public/img/${name}`); };
调用时仅传入前两个参数await resizeImage(req.file.buffer, req.file.filename),TypeScript报错EXPECTED 3 ARGUMENTS, BUT GOT 2,但我希望使用默认值,无需传入第三个参数。
尝试过将第三个参数设为可选、定义ResizeOptions接口并使用Partial<ResizeOptions>类型等写法,均无法解决报错;同时不想用对象字面量作为默认参数,因为ESLint的unicorn/no-object-as-default-parameter规则警告存在参数覆盖风险:
const resizeImage = async function resizeImage( buffer: Buffer, name: string, resizeOptions = { width: 500, height: 500, } // Do not use an object literal as default for parameter `resizeOptions`. [unicorn/no-object-as-default-parameter ) { ... }
规则说明:默认参数不应通过对象字面量传递给函数。
foo = {a: false}在仅使用一个选项时没问题,但添加额外选项后,仅传递{a: true}会替换整个默认对象(比如后续新增b: true时),因此应使用对象解构替代。
请问如何实现既让TypeScript不报错,又符合ESLint规范的写法?
解决方案
要同时满足TypeScript类型检查和ESLint规则,只需给第三个参数添加可选标记的默认空对象,同时保留解构参数的默认值即可,具体有两种清晰写法:
写法1:直接在参数中处理
const resizeImage = async function resizeImage( buffer: Buffer, name: string, { width = 500, height = 500, ...others }: { width?: number; height?: number } = {} ) { Logger.info('hello from resizeImage'); await sharp(buffer) .resize({ fit: sharp.fit.cover, width, height, ...others, }) .toFormat('jpeg') .jpeg({ quality: 90 }) .toFile(`public/img/${name}`); };
核心修改点:
- 给第三个参数的类型后追加
= {},表示未传入该参数时默认使用空对象 - 解构时的
width和height保留各自默认值,确保即使传入的对象不含这两个属性,也能正常使用默认值
写法2:定义独立接口(更易扩展)
如果参数类型后续需要扩展,建议先定义接口再使用:
interface ResizeOptions { width?: number; height?: number; // 可添加sharp支持的其他resize配置项 } const resizeImage = async function resizeImage( buffer: Buffer, name: string, { width = 500, height = 500, ...others }: ResizeOptions = {} ) { Logger.info('hello from resizeImage'); await sharp(buffer) .resize({ fit: sharp.fit.cover, width, height, ...others, }) .toFormat('jpeg') .jpeg({ quality: 90 }) .toFile(`public/img/${name}`); };
修改后效果:
- TypeScript允许仅传入前两个参数,因为第三个参数有合法默认值
- 解构赋值的写法完全符合ESLint
unicorn/no-object-as-default-parameter规则,避免对象覆盖风险 - 后续扩展参数时,只需在接口中新增属性,无需修改默认值逻辑
内容的提问来源于stack exchange,提问作者gipo355
相关产品推荐
相关产品推荐

