You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写带默认值的可选对象参数,满足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}`);
};

修改后效果:

  1. TypeScript允许仅传入前两个参数,因为第三个参数有合法默认值
  2. 解构赋值的写法完全符合ESLintunicorn/no-object-as-default-parameter规则,避免对象覆盖风险
  3. 后续扩展参数时,只需在接口中新增属性,无需修改默认值逻辑

内容的提问来源于stack exchange,提问作者gipo355

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:55:33