flatten-object.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import type { Flatten } from '@vben-core/typings';
  2. import { capitalizeFirstLetter } from '@vben-core/toolkit';
  3. /**
  4. * 将嵌套对象扁平化
  5. * @param obj - 需要扁平化的对象
  6. * @param parentKey - 父键名,用于递归时拼接键名
  7. * @param result - 存储结果的对象
  8. * @returns 扁平化后的对象
  9. *
  10. * 示例:
  11. * const nestedObj = {
  12. * user: {
  13. * name: 'Alice',
  14. * address: {
  15. * city: 'Wonderland',
  16. * zip: '12345'
  17. * }
  18. * },
  19. * items: [
  20. * { id: 1, name: 'Item 1' },
  21. * { id: 2, name: 'Item 2' }
  22. * ],
  23. * active: true
  24. * };
  25. * const flatObj = flattenObject(nestedObj);
  26. * console.log(flatObj);
  27. * 输出:
  28. * {
  29. * userName: 'Alice',
  30. * userAddressCity: 'Wonderland',
  31. * userAddressZip: '12345',
  32. * items: [ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' } ],
  33. * active: true
  34. * }
  35. */
  36. function flattenObject<T extends Record<string, any>>(
  37. obj: T,
  38. parentKey: string = '',
  39. result: Record<string, any> = {},
  40. ): Flatten<T> {
  41. Object.keys(obj).forEach((key) => {
  42. const newKey = parentKey
  43. ? `${parentKey}${capitalizeFirstLetter(key)}`
  44. : key;
  45. const value = obj[key];
  46. if (value && typeof value === 'object' && !Array.isArray(value)) {
  47. flattenObject(value, newKey, result);
  48. } else {
  49. result[newKey] = value;
  50. }
  51. });
  52. return result as Flatten<T>;
  53. }
  54. export { flattenObject };
  55. // 定义递归类型,用于推断扁平化后的对象类型
  56. // 限制递归深度的辅助类型
  57. // type FlattenDepth<
  58. // T,
  59. // Depth extends number,
  60. // CurrentDepth extends number[] = [],
  61. // > = {
  62. // [K in keyof T as CurrentDepth['length'] extends Depth
  63. // ? K
  64. // : T[K] extends object
  65. // ? `${CurrentDepth['length'] extends 0 ? UnCapitalize<K & string> : Capitalize<K & string>}${keyof FlattenDepth<T[K], Depth, [...CurrentDepth, 1]> extends string ? Capitalize<keyof FlattenDepth<T[K], Depth, [...CurrentDepth, 1]>> : ''}`
  66. // : `${CurrentDepth['length'] extends 0 ? UnCapitalize<K & string> : Capitalize<K & string>}`]: CurrentDepth['length'] extends Depth
  67. // ? T[K]
  68. // : T[K] extends object
  69. // ? FlattenDepth<T[K], Depth, [...CurrentDepth, 1]>[keyof FlattenDepth<
  70. // T[K],
  71. // Depth,
  72. // [...CurrentDepth, 1]
  73. // >]
  74. // : T[K];
  75. // };
  76. // type Flatten<T, Depth extends number = 4> = FlattenDepth<T, Depth>;