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

为何flatten函数返回类型为Set<unknown>而非Set<number>?

为什么调用flatten([[1, 2, 3]])返回Set而非Set?

先看你的代码:

export function flatten<T>(iterable: Iterable<Iterable<T>>): Set<T> {
  const result = new Set<T>();
  for (const iter of iterable) {
    for (const val of iter) {
      result.add(val);
    }
  }
  return result;
}

const foo = flatten([[1, 2, 3]]); // foo类型为Set<unknown>,而非预期的Set<number>

问题原因

TypeScript的类型推断在这里存在局限性:当你传入嵌套数组字面量[[1,2,3]]时,TS无法自动将泛型参数T推断为number。

具体来说,TS会先把[[1,2,3]]推断为number[][]类型,但函数参数要求的是Iterable<Iterable<T>>。由于嵌套的Iterable类型结构相对抽象,TS的推断器无法自动将内层数组的元素类型number关联到泛型T,最终只能 fallback 到最宽泛的unknown类型,导致返回值变成Set<unknown>。

解决办法

有几种方式可以让类型推断正常工作:

  • 显式指定泛型参数:直接告诉TST的类型

    const foo = flatten<number>([[1, 2, 3]]); // foo类型为Set<number>
    
  • 优化函数的泛型定义:调整泛型约束,让推断更精准
    把函数改成让外层Iterable的元素明确是Iterable<T>的子类型,这样TS能顺着内层元素类型推断出T:

    export function flatten<T, U extends Iterable<T>>(iterable: Iterable<U>): Set<T> {
      const result = new Set<T>();
      for (const iter of iterable) {
        for (const val of iter) {
          result.add(val);
        }
      }
      return result;
    }
    
    const foo = flatten([[1, 2, 3]]); // 自动推断为Set<number>
    
  • 给参数加类型注解:提前明确参数的嵌套Iterable类型

    const input: Iterable<Iterable<number>> = [[1, 2, 3]];
    const foo = flatten(input); // foo类型为Set<number>
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:45:29