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

如何让TypeScript支持可选参数?解决多参数函数编译报错

解决TypeScript中可变参数函数的类型报错问题

问题场景

以下JavaScript代码运行正常,但转成TypeScript时出现类型错误:

t.ts:11:34 - error TS2554: Expected 1 arguments, but got 6.    
11 console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 2))
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

t.ts:14:34 - error TS2554: Expected 1 arguments, but got 6.
14 console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 4))
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

原JS代码如下:

var obj = [{
  "category1": {
    nested: {
      a: 'string',
      b: [69, 13, 15]
    }
  },
  "category2": "2",
}];

console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 2))
// 输出 15

console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 4))
// 输出 undefined at key 4

function where_undefined(obj) {
  var args = Array.prototype.slice.call(arguments)
  args.shift();
  while (args.length) {
    var arg = args.shift();
    if (obj[arg] === undefined) {
      console.log("undefined at key " + arg);
      break;
    } else {
      obj = obj[arg];
    }
  }
  return obj;
}

解决方案

方法1:使用剩余参数(推荐)

TypeScript支持剩余参数语法,可接收任意数量的后续参数,同时保证类型检查。改造后的函数如下:

const obj = [{
  "category1": {
    nested: {
      a: 'string',
      b: [69, 13, 15]
    }
  },
  "category2": "2",
}];

console.log(whereUndefined(obj, 0, 'category1', 'nested', 'b', 2))
// 输出 15

console.log(whereUndefined(obj, 0, 'category1', 'nested', 'b', 4))
// 输出 undefined at key 4

// 剩余参数 keys 接收任意数量的 string | number 类型参数
function whereUndefined(obj: unknown, ...keys: (string | number)[]) {
  let current = obj;
  for (const key of keys) {
    // 先判断当前值是否为对象/数组,避免访问非索引类型的属性
    if (typeof current === 'object' && current !== null) {
      if (current[key as keyof typeof current] === undefined) {
        console.log(`undefined at key ${key}`);
        break;
      }
      current = current[key as keyof typeof current];
    } else {
      console.log(`cannot access key ${key} on non-object value`);
      break;
    }
  }
  return current;
}

优化点说明:

  • 用...keys: (string | number)[]声明可变参数,明确告诉TS函数可接收任意数量的字符串或数字类型键名
  • 替换arguments为剩余参数,符合现代JS/TS写法且更类型安全
  • 添加类型断言key as keyof typeof current,解决属性访问的类型报错
  • 增加非对象值判断,避免运行时错误

方法2:保留arguments并兼容类型(不推荐)

如果一定要保留arguments用法,可通过以下方式兼容,但会损失部分类型安全性:

// 方式1:用any绕过类型检查(快速但失去TS类型优势)
function whereUndefined(obj: any, ...args: any[]) {
  const keys = Array.prototype.slice.call(arguments);
  keys.shift();
  let current = obj;
  while (keys.length) {
    const arg = keys.shift();
    if (current[arg] === undefined) {
      console.log(`undefined at key ${arg}`);
      break;
    } else {
      current = current[arg];
    }
  }
  return current;
}

// 方式2:函数重载(适合明确参数数量范围的场景)
function whereUndefined(obj: unknown, key1: string | number): unknown;
function whereUndefined(obj: unknown, key1: string | number, key2: string | number): unknown;
function whereUndefined(obj: unknown, ...keys: (string | number)[]): unknown {
  // 实现逻辑同方法1
}

报错原因

TypeScript是强类型语言,原JS函数仅声明了一个参数obj,但调用时传入了多个参数,TS类型检查会判定参数不匹配,因此抛出Expected 1 arguments, but got 6错误。通过声明可变参数的类型,让TS识别函数可接收多个参数,即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:20:26