TypeScript中如何扁平化嵌套对象?用lodash flatMapDeep遇无限循环
解决TypeScript嵌套对象扁平化及lodash flatMapDeep无限循环问题
问题根源
你写的flattenExtensions触发无限循环,核心原因是getTests函数没有接收当前迭代的元素,反而一直操作外层的整个extension数组——每次调用flatMapDeep(extension, getTests)都会重新遍历整个数组,递归调用永远停不下来。另外你的TypeScript接口和实际数据结构不匹配:terms和tests在数据里是数组,但接口里定义成了单个对象,这会导致类型错误。
修正后的接口定义
先把接口调整成和实际数据一致的结构:
export interface IExtension { [key: string]: any; extensionId: number | null; assetId: number | null; extensionName: string | null; terms: IExtensionTerms[]; // 改为数组类型 } export interface IExtensionTerms { [key: string]: any; extensionTermId: number | null; extensionId: number | null; modificationVersion: number | null; tests: IExtensionTest[]; // 改为数组类型 } export interface IExtensionTest { extensionTestId: number | null; extensionTermId: number | null; testTypeId: number | null; testTypeName: string | null; }
实现扁平化的两种方法
方法1:原生嵌套遍历(简单直观)
直接逐层遍历extension、term、test,合并每层的属性,生成最终的扁平化数组:
const flattenExtensions = (extensions: IExtension[]): (IExtension & IExtensionTerms & IExtensionTest)[] => { const result: (IExtension & IExtensionTerms & IExtensionTest)[] = []; extensions.forEach(extension => { extension.terms.forEach(term => { term.tests.forEach(test => { result.push({ ...extension, ...term, ...test, // 移除嵌套属性避免冗余 terms: undefined, tests: undefined }); }); }); }); return result; };
方法2:用lodash的flatMap(避免递归误区)
如果想用lodash,用flatMap逐层处理,不要用flatMapDeep做无边界递归:
import { flatMap } from 'lodash'; const flattenExtensions = (extensions: IExtension[]): (IExtension & IExtensionTerms & IExtensionTest)[] => { return flatMap(extensions, extension => flatMap(extension.terms, term => term.tests.map(test => ({ ...extension, ...term, ...test, terms: undefined, tests: undefined })) ) ); };
测试验证
用你提供的测试数据调用函数:
const testData: IExtension[] = [ { "extensionId": 1, "assetId": 1996323923, "extensionName": "Extension 1", "terms": [ { "extensionTermId": 2, "extensionId": 1, "modificationVersion": 0, "tests": [ {"extensionTestId": 1,"extensionTermId": 2,"testTypeId": 1,"testTypeName": "Debt Yield"}, {"extensionTestId": 2,"extensionTermId": 2,"testTypeId": 3,"testTypeName": "LTV"} ] } ] } ]; console.log(flattenExtensions(testData));
会生成包含两个test对应扁平化对象的数组,和你期望的结构一致。
内容的提问来源于stack exchange,提问作者Conrad Addo
相关产品推荐
相关产品推荐

