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

TypeScript枚举用Object.keys获键含索引值及动态过滤属性问题

问题解答

一、为什么Object.keys(IAgentTask)会返回数字索引?

你定义的是TypeScript的数字枚举,这类枚举编译为JavaScript时会生成双向映射的对象:

  • 正向映射:字符串键(如firstName)对应自动分配的数字值(从0开始递增)
  • 反向映射:数字值对应回字符串键

编译后的代码大致如下:

export var IAgentTask;
(function (IAgentTask) {
    IAgentTask[IAgentTask["firstName"] = 0] = "firstName";
    IAgentTask[IAgentTask["lastName"] = 1] = "lastName";
    // ...其余枚举项的映射
})(IAgentTask || (IAgentTask = {}));

所以Object.keys(IAgentTask)会把正向的字符串键和反向的数字转字符串键('0'、'1'...)一起返回,这就是你看到数字索引的原因。

如果只想获取枚举的纯字符串键,可以过滤掉数字类型的键:

const enumStringKeys = Object.keys(IAgentTask).filter(key => isNaN(Number(key)));

二、如何正确过滤response.tasks的属性?

你的原有代码有两个核心问题:

  1. 使用for (let key in Object.keys(IAgentTask))遍历数组时,拿到的是数组索引('0'、'1'这类字符串),而非枚举键名,导致response.tasks[j][key]始终为undefined
  2. 直接遍历枚举键处理task属性不够准确,应该针对每个task自身的属性做过滤

推荐实现(创建新对象保留允许字段,避免修改原对象)

const allowedFields = new Set(this.filteredRowsPreference.map(x => x.fieldDbKey));

// 遍历每个任务,生成只保留允许字段的新对象
response.tasks = response.tasks.map(task => {
  const filteredTask: Partial<typeof task> = {};
  Object.keys(task).forEach(key => {
    if (allowedFields.has(key)) {
      filteredTask[key] = task[key];
    }
  });
  return filteredTask as typeof task;
});

若需直接删除属性(不推荐,会修改原对象)

const allowedFields = new Set(this.filteredRowsPreference.map(x => x.fieldDbKey));

for (const task of response.tasks) {
  // 遍历当前任务的所有属性键
  Object.keys(task).forEach(key => {
    if (!allowedFields.has(key)) {
      delete task[key];
    }
  });
}

补充说明

  • 用Set存储允许字段是为了提升查询效率(从O(n)优化为O(1)),字段数量少时用数组includes也可行
  • 直接遍历task自身的属性,比遍历枚举键更准确,避免枚举键与task属性不匹配的问题

内容的提问来源于stack exchange,提问作者questions ss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:05:18