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

求助:将JavaScript对象扁平化函数转换为TypeScript(参数类型困惑)

解决对象扁平化函数的TypeScript类型定义问题

首先修正原代码里的一个逻辑问题:contact: +91-999999999会被JavaScript解析为数值计算式(结果为-999999908),应该改成字符串形式contact: "+91-999999999"来保留正确的联系方式格式。

以下是完整的TypeScript改造方案:

1. 定义递归扁平化类型

我们需要一个泛型类型来描述扁平化后的对象结构,它会递归地将嵌套对象的键用.拼接:

type FlattenedObject<T> = T extends object
  ? {
      [K in keyof T as T[K] extends object ? `${Exclude<K, symbol>}.${keyof FlattenedObject<T[K]> & string}` : Exclude<K, symbol>]: T[K] extends object
        ? FlattenedObject<T[K]>[keyof FlattenedObject<T[K]>]
        : T[K]
    }
  : T;

这个类型的作用:

  • 若T是对象类型,遍历所有键K
  • 若T[K]也是对象,将K与T[K]扁平化后的键拼接为K.subKey格式
  • 最终生成所有键为扁平路径、值为原嵌套值的类型

2. 改造扁平化函数

给函数添加泛型参数,指定参数和返回值类型,同时优化遍历逻辑避免原型链污染:

// 定义原始对象的类型
type OriginalObject = {
  Company: string;
  Address: string;
  contact: string;
  mentor: {
    HTML: string;
    CSS: string;
    JavaScript: string;
  };
};

// 声明对象并指定类型
const ob: OriginalObject = {
  Company: "GeeksforGeeks",
  Address: "Noida",
  contact: "+91-999999999",
  mentor: {
    HTML: "GFG",
    CSS: "GFG",
    JavaScript: "GFG"
  }
};

// 带类型约束的扁平化函数
const flattenObj = <T extends object>(ob: T): FlattenedObject<T> => {
  const result = {} as FlattenedObject<T>;

  for (const i in ob) {
    // 仅遍历对象自身属性,避免原型链属性干扰
    if (Object.prototype.hasOwnProperty.call(ob, i)) {
      const value = ob[i];
      // 判断是否为非数组的对象类型,递归处理
      if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
        const temp = flattenObj(value);
        for (const j in temp) {
          if (Object.prototype.hasOwnProperty.call(temp, j)) {
            result[`${i}.${j}` as keyof FlattenedObject<T>] = temp[j];
          }
        }
      } else {
        result[i as keyof FlattenedObject<T>] = value as FlattenedObject<T>[keyof FlattenedObject<T>];
      }
    }
  }
  return result;
};

// 调用函数,TypeScript会自动推断返回值的完整类型
const flattened = flattenObj(ob);
console.log(flattened);

关键细节说明

  • 使用Object.prototype.hasOwnProperty.call过滤原型链属性,提升代码健壮性
  • 通过as进行类型断言,弥补TypeScript对递归扁平化类型的自动推断局限
  • 泛型T extends object确保参数仅接受对象类型,排除原始类型和数组
  • FlattenedObject<T>会提供完整的类型提示,比如访问flattened["mentor.HTML"]时会有明确的类型校验

输出结果

运行后控制台输出:

{
  Company: 'GeeksforGeeks',
  Address: 'Noida',
  contact: '+91-999999999',
  'mentor.HTML': 'GFG',
  'mentor.CSS': 'GFG',
  'mentor.JavaScript': 'GFG'
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:35:24