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

为何TypeScript递归函数会报扩展参数相关警告?如何解决

TypeScript递归函数参数展开错误分析与修复

原函数代码

const checkNested = ((obj: any, attr: string, ...rest: any[]): boolean => {
  if (obj === undefined || obj === null) return false
  if (rest.length === 0 && obj.hasOwnProperty(attr)) return true
  return checkNested(obj[attr], ...rest)
})

错误提示

A spread argument must either have a tuple type or be passed to a rest parameter.
翻译:展开参数必须是元组类型,或者传递给剩余参数

错误含义

这个错误是TypeScript类型检查的规则限制:当使用...语法展开数组作为函数参数时,TypeScript要求该数组要么是元组类型(长度和元素类型完全明确的数组),要么是被传递给函数的剩余参数(即定义为...参数名的形参)。

原代码中,rest被定义为any[](任意类型的数组),递归调用checkNested时,函数的第二个参数要求是string类型,但TypeScript无法确认rest的第一个元素是string,也无法保证rest的长度匹配函数参数的要求,因此触发类型检查错误。

修复方案

方案一:使用函数重载明确参数类型

通过重载定义不同参数长度的类型约束,让TypeScript能正确推断展开后的参数类型:

// 重载:仅检查最后一个属性的情况
function checkNested(obj: any, attr: string): boolean;
// 重载:还有后续属性需要检查的情况
function checkNested(obj: any, attr: string, ...rest: [string, ...string[]]): boolean;
// 函数实现
function checkNested(obj: any, attr: string, ...rest: string[]): boolean {
  if (obj === undefined || obj === null) return false;
  if (rest.length === 0 && obj.hasOwnProperty(attr)) return true;
  return checkNested(obj[attr], ...rest);
}

这里用[string, ...string[]]这个剩余元组类型,确保rest至少包含一个字符串,递归展开后能匹配函数的参数要求。

方案二:统一使用剩余参数接收属性

把所有要检查的属性都放到剩余参数中,递归时传递剩余的属性数组:

const checkNested = ((obj: any, ...attrs: string[]): boolean => {
  if (obj === undefined || obj === null) return false;
  const [currentAttr, ...restAttrs] = attrs;
  if (restAttrs.length === 0 && obj.hasOwnProperty(currentAttr)) return true;
  return checkNested(obj[currentAttr], ...restAttrs);
})

这种方式下,restAttrs是string[]类型,展开后传递给函数的...attrs剩余参数,完全符合TypeScript的类型规则,错误会自动消除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:00:08