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

