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

TypeScript中如何遍历递归生成器 解决子集生成器隐式any报错

报错原因

该报错是TypeScript的类型推断限制导致:对于存在递归调用的生成器函数,TS无法自动推导返回值类型,因此会抛出隐式any的错误。
除此之外你提供的原代码还存在两个运行时问题:

  • while循环中未修改offset的值,会进入无限死循环
  • 直接对递归返回的subset执行push操作,会修改原数组对象,导致生成的子集结果异常
修复方案

完整修复代码

我们给生成器添加显式的返回类型注解,同时修复逻辑问题,还可以引入泛型实现类型安全,避免使用any:

export class GenerateThings {
    // 泛型T对应输入数组的元素类型,返回Generator类型,生成的每一项是T类型的数组
    static *generateSubsets<T>(elements: T[], offset: number = 0): Generator<T[]> {
        // 原while改为if,避免死循环
        if (offset < elements.length) {
            const current = elements[offset];
            // 递归生成后续元素的所有子集
            for (const subset of this.generateSubsets(elements, offset + 1)) {
                // 返回不包含当前元素的子集
                yield subset;
                // 返回包含当前元素的子集,用展开语法做浅拷贝避免修改原对象
                yield [current, ...subset];
            }
        } else {
            // 递归终止条件,返回空集
            yield [];
        }
    }
}

如果不想调整原逻辑,仅需要解决TS编译报错,只需要给原方法添加返回类型注解即可:

export class GenerateThings {
    // 仅添加Generator<any[]>的返回类型注解
    static *generateSubsets(elements: any[], offset: number = 0): Generator<any[]> {
        while (offset < elements.length) {
            const first = elements[offset];
            for (const subset of this.generateSubsets(elements, offset + 1)) {
                subset.push(first);
                yield subset;
            }
        }
        yield [];
    }
}
遍历方法

生成器返回的是可迭代对象,直接用for...of语法遍历即可:

// 测试示例
const testArr = [1, 2, 3];
for (const subset of GenerateThings.generateSubsets(testArr)) {
    console.log(subset);
}
// 输出顺序:[], [3], [2], [2,3], [1], [1,3], [1,2], [1,2,3]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:00:00