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

TypeScript中使用枚举作为键提取值并转换枚举类型报错求助

问题

我在尝试以枚举类型作为键从对象中提取值,并将其转换为该枚举类型时遇到了大量错误。提取类型后,我将其传入函数以根据该类型进一步处理数据。代码示例如下:

export enum TestElement {
  Type = 'T',
  Serial = 'S',
}

const data = '{"TEST1":{"T":"XX2","S":8374373}}';

const parsed: object = JSON.parse(data);

// Get the first element
const extracted: object = Object.values(parsed)[0];

// Get the type
const type: TestElement = extracted[TestElement.Type];

handler(type, extracted)();

在const type: TestElement = extracted[TestElement.Type]处出现错误:

Element implicitly has an 'any' type because expression of type 'TestElement.Type' can't be used to index type '{}'.
  Property '[TestElement.Type]' does not exist on type '{}'.ts(7053)

另外一段代码:

const handler = (
  type: TestElement,
  data: object,
): (() => void) =>
  processTypes[type]
    ? () => processTypes[type](data[type]())
    : () => {
        throw new Error(
          'Type not supported or unknown',
        );
      };

在processTypes[type](data[type]())处出现错误:

Element implicitly has an 'any' type because expression of type 'TestElement' can't be used to index type '{}'.
  Property '[TestElement.Type]' does not exist on type '{}'.ts(7053)

还有processTypes的定义:

const processTypes: {
  [key: string]: (data: {[key in TestElement]: string}) => void;
} = {
  XX1: data => {
    console.log({data});
  },
  XX2: data => {
    console.log({data});
  },
};

请问我哪里出错了?是否有正确的实现方式?

问题分析

核心问题是你给parsed和extracted都标注了object类型,TypeScript中object是最宽泛的顶层类型,不包含任何具体属性信息,导致TS无法确认extracted上存在TestElement.Type对应的键,进而抛出索引错误。

此外还有几个细节问题:

  • data[type]()是错误写法,data[type]是属性值而非函数,不需要加调用符号()
  • processTypes的键是XX1、XX2这类业务标识字符串,但你用TestElement枚举类型的值去索引它,类型不匹配
  • processTypes的参数类型定义中,Serial对应的JSON值是数字,但你定义成了string,类型不兼容
修正后的实现

通过定义明确的类型接口,给JSON解析结果指定精准类型,逐步修正所有类型匹配问题:

export enum TestElement {
  Type = 'T',
  Serial = 'S',
}

// 定义单个数据项的结构类型,匹配JSON中的实际值类型
interface ItemData {
  [TestElement.Type]: 'XX1' | 'XX2';
  [TestElement.Serial]: number;
}

// 定义解析后的整体数据结构
interface ParsedData {
  [key: string]: ItemData;
}

const dataStr = '{"TEST1":{"T":"XX2","S":8374373}}';

// 给JSON.parse添加类型断言,明确解析后的结构类型
const parsed = JSON.parse(dataStr) as ParsedData;

// 提取第一个元素,此时extracted自动推导为ItemData类型
const extracted = Object.values(parsed)[0];

// 提取类型标识,自动推导为'XX1'|'XX2'
const type = extracted[TestElement.Type];

// 重新定义processTypes,键类型与type严格匹配,参数类型匹配ItemData
const processTypes: {
  [K in typeof type]: (data: ItemData) => void;
} = {
  XX1: data => {
    console.log('处理XX1类型数据:', data);
  },
  XX2: data => {
    console.log('处理XX2类型数据:', data);
  },
};

// 修正handler的类型定义,确保参数和逻辑匹配
const handler = (
  type: typeof type,
  data: ItemData,
): (() => void) => {
  const processor = processTypes[type];
  return processor 
    ? () => processor(data) 
    : () => { throw new Error('不支持的类型或未知类型'); };
};

// 调用测试
handler(type, extracted)();
关键修正点说明
  • 用明确的接口类型替代宽泛的object,让TS能识别对象的属性结构
  • 移除data[type]()中多余的(),修正语法错误
  • 让processTypes的键类型和extracted[TestElement.Type]的类型严格对齐,消除类型不兼容问题
  • 调整参数类型,确保Serial的数字类型与JSON中的实际值一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:50:19