Typescript中递归调用array.map处理嵌套数组的类型定义方法
解决方案
问题根源
你之前的写法报错核心有两个原因:
- 没有定义递归的嵌套数组类型,仅声明了一层
string | string[]的联合类型,无法匹配深层嵌套的结构; - TypeScript不会自动对函数内部的返回值和泛型条件类型做匹配推导,需要明确的递归类型定义兜底,必要时加安全的类型断言。
正确实现
首先定义通用的递归嵌套数组类型,支持任意层级的嵌套:
// 泛型嵌套数组类型,T为基础类型,支持任意层级嵌套 type NestedArray<T> = T | NestedArray<T>[];
方案1:函数重载实现(无需断言,适配绝大多数场景)
function mapToNumber(item: string): number; function mapToNumber(item: NestedArray<string>): NestedArray<number>; function mapToNumber(item: NestedArray<string>): NestedArray<number> { if (Array.isArray(item)) { return item.map(mapToNumber); } return Number(item); } // 测试用例 const strArr: NestedArray<string>[] = ["1", "2", ["3", "4"], "5"]; console.log(strArr.map(mapToNumber)); // 类型推导为 NestedArray<number>[],无报错
方案2:泛型递归条件类型(可保留输入的字面量类型结构)
如果你需要让输出类型严格匹配输入的嵌套结构(比如输入是[string, string, [string, string], string],输出自动推导为[number, number, [number, number], number]),可以用这个方案:
type MapToNumber<T> = T extends string ? number : { [K in keyof T]: MapToNumber<T[K]> }; function mapToNumber<T extends NestedArray<string>>(item: T): MapToNumber<T> { if (Array.isArray(item)) { // 此处断言完全安全,运行逻辑和类型定义完全匹配 return item.map(mapToNumber) as MapToNumber<T>; } return Number(item) as MapToNumber<T>; } // 测试用例 const strArr = ["1", "2", ["3", "4"], "5"] as const; const result = mapToNumber(strArr); // result的类型会被精确推导为 readonly [1, 2, readonly [3, 4], 5]
内容的提问来源于stack exchange,提问作者crazyones110
相关产品推荐
相关产品推荐

