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
相关产品推荐
相关产品推荐

