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

使用flatMap返回数组时TypeScript类型推断错误求助

TypeScript flatMap 泛型类型推断异常:返回 User[][] 而非预期的 User[]

我在编写代码时遇到类型推断问题:调用useInfiniteData函数,实际输出是正确的User[],但TypeScript却推断其返回类型为User[][],即使已经使用了flatMap()做扁平化处理。

原代码如下:

type User = {
  id: number
  firstName: string
}

type UserResponse = {
  items: User[]
  nextCursor: number
  hasNextPage: boolean
}

type InfiniteData<PageType> = {
  pages: PageType[]
}

const data: InfiniteData<UserResponse> = {
  pages: [
    {
      items: [
        {id: 1, firstName: 'Bob'},
        {id: 2, firstName: 'Alice'}
      ],
      nextCursor: 1,
      hasNextPage: false
    }
  ]
}

function useInfiniteData<TData, TValue>(
  data: InfiniteData<TData>,
  selectFn: (page: TData) => TValue
) {
  return data.pages.flatMap((page) => {
    // Returns a User[]
    return selectFn(page)
  })
}

// Expect User[] because flatMap flattens by one level,
// but TS thinks it's User[][]
const result = useInfiniteData(data, (page) => page.items)
// Output:
// result = [{
//   "id": 1,
//   "firstName": "Bob"
// }, {
//   "id": 2,
//   "firstName": "Alice"
// }] 

问题原因

泛型TValue没有约束为可扁平化的类型,TypeScript无法识别selectFn(page)返回的是数组。此时flatMap的返回类型会被推断为TValue[],当TValue本身是User[]时,最终类型就变成了User[][]。

解决方案

修改泛型定义,明确selectFn的返回值为数组(或可迭代)类型,让TypeScript能正确推断flatMap的扁平化结果:

方案1:限定返回数组类型

function useInfiniteData<TData, TValue>(
  data: InfiniteData<TData>,
  selectFn: (page: TData) => TValue[] // 明确返回数组
) {
  return data.pages.flatMap((page) => {
    return selectFn(page)
  })
}

方案2:支持可迭代类型(更灵活)

function useInfiniteData<TData, TValue>(
  data: InfiniteData<TData>,
  selectFn: (page: TData) => Iterable<TValue> // 支持所有可迭代类型
) {
  return data.pages.flatMap((page) => {
    return selectFn(page)
  })
}

修改后,result的类型会被正确推断为User[],与实际输出一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:12:22