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

Angular中如何将JSON返回的字符串映射为TypeScript枚举类型

问题原因

TypeScript 静态类型检查时,导入的JSON文件字段会被默认推导为string类型,与OrderModel中定义的Status枚举类型不兼容,直接赋值就会抛出 Type 'string' is not assignable to type 'Status' 错误。另外需要注意:直接把普通JSON对象赋值给Class类型的变量,不会生成对应的类实例,只是结构相似的 plain object。

可行方案

根据实际业务场景选以下任意一种即可:

1. 显式遍历映射(最稳妥,推荐生产环境用)

遍历JSON数组,逐字段赋值生成真正的OrderModel实例,同时完成字符串到枚举的转换,还可以加容错逻辑处理非法值。
修改后的OrderService代码如下:

import { OrderModel } from '../../models/order.model';
import { Status } from "../enums/status.enum";
import orderData from '../json/order.json';

@Injectable({
  providedIn: 'root'
})
export class OrderService{
  orderModel: OrderModel[] = [];

  constructor() {
    this.orderModel = orderData.map(item => {
      const instance = new OrderModel();
      instance.id = item.id;
      instance.notification = item.notification;
      instance.action = item.action;
      // 字符串转枚举:匹配枚举键值
      const enumKey = item.status.toUpperCase() as keyof typeof Status;
      instance.status = Status[enumKey];
      
      // 可选:加兜底容错,遇到非法枚举值返回默认值
      // if (!Object.values(Status).includes(instance.status)) {
      //   instance.status = Status.LOW;
      // }

      // 如果后端返回值大小写不固定,可以用自定义映射表替代上面的转换逻辑
      // const statusMap: Record<string, Status> = {
      //   'high': Status.HIGH,
      //   'High': Status.HIGH,
      //   'medium': Status.MEDIUM,
      //   'Medium': Status.MEDIUM,
      //   'low': Status.LOW,
      //   'Low': Status.LOW
      // }
      // instance.status = statusMap[item.status] ?? Status.LOW;

      return instance;
    });
  }

  getOrderStatus() {
   console.log(this.orderModel)
  }
}

转换逻辑说明:当前定义的Status是字符串枚举,枚举键为全大写的HIGH/MEDIUM/LOW,对应值为首字母大写的"High"/"Medium"/"Low",和JSON返回的字符串完全匹配,把JSON中的status值转大写后作为键取枚举值,就能得到正确的枚举成员。

2. 类型断言(适合确定返回值100%匹配枚举的场景)

如果不需要生成OrderModel类实例(即OrderModel仅做类型约束,没有定义类方法),且能保证后端返回的status值永远和枚举值一致,可以直接用类型断言跳过TS检查,写法最简洁:

orderModel: OrderModel[] = orderData as OrderModel[];

注意:该方式仅在静态类型层面骗过TS检查,运行时不会做任何类型转换、校验,也不会生成类实例,后续如果类新增方法,调用时会直接报错。

3. 新增JSON类型声明(适配多场景复用)

在项目全局类型声明文件(一般是src/typings.d.ts,没有则新建)中,给导入的order.json添加明确的类型定义,指定status字段为Status类型,之后所有地方导入该JSON文件都不会报类型错误:

declare module '*/order.json' {
  import { Status } from "../enums/status.enum";
  const data: Array<{
    id: number;
    notification: string;
    action: string;
    status: Status;
  }>;
  export default data;
}

该方式和类型断言一样,仅做静态类型约束,没有运行时转换逻辑。

选型建议
  • 生产环境、需要类实例、需要做字段容错的场景,选第一种显式映射方案,鲁棒性最高
  • 内部项目、接口返回值完全可控、仅做类型约束的场景,可以选类型断言或者JSON类型声明方案,代码更简洁

内容的提问来源于stack exchange,提问作者C.Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:06:47