当前位置: 首页 > news >正文

TypeScript枚举类型应用:前后端状态码映射的最简方案

介绍

这篇文章来谈一下 TypeScript 中的枚举类型(Enum)以及一些最佳实践。事情的起因是这样的,今天看到自己之前写的一段代码,感觉不是很好,于是想优化一下,期间用到了枚举类型,遂记录一下。为了方便理解,我将原来的例子简化一下。

业务需求

业务需求是这样的:我们要实现一个Job系统,你可以将其想象为Jenkins Job类似的东西,每个Job有一个状态,状态可以是以下几种:

  • PENDING:等待执行

  • RUNNING:正在执行

  • SUCCESS:执行成功

  • FAILED:执行失败

  • CANCELED:执行被取消

Job的状态信息由后端返回,前端只负责展示,也不需要实时刷新。很简单的需求,对吧?我的原始代码如下:

原始代码

前端数据类型定义, 首先定义一个字面量用来保存Job状态,然后定义一个Job接口来描述Job对象。

// 定义Job状态字面量
type JobStatus = 'PENDING' | 'RUNNING' | 'SUCCESS' | 'FAILED' | 'CANCELED';// 每个Job包含id、name和status三个属性
interface Job {id: string;name: string;status: JobStatus;
}

后端返回数据如下,可以看到后端是用数字类型来表示状态的。

const jobData = [{ id: '1', name: 'Job 1', status: 1 }, // PENDING{ id: '2', name: 'Job 2', status: 2 }, // RUNNING{ id: '3', name: 'Job 3', status: 3 }, // SUCCESS{ id: '4', name: 'Job 4', status: 4 }, // FAILED{ id: '5', name: 'Job 5', status: 5 }, // CANCELED
];

为了将后端返回的数字类型和前端定义的Job Status对应起来,我又额外写了一个映射函数:

function mapJobStatus(status: number): JobStatus {switch (status) {case 1:return 'PENDING';case 2:return 'RUNNING';case 3:return 'SUCCESS';case 4:return 'FAILED';case 5:return 'CANCELED';default:throw new Error(`Unknown status: ${status}`);}
}

接下来就是展示了,展示Job状态时,用户不想看到全大写的状态,而是想看到首字母大写的状态,所以我又写了一个函数来处理这个问题:

function getJobDisplayName(status: JobStatus): string {return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();
}/* 转换后的状态字符串如下:
PENDING -> Pending
RUNNING -> Running
SUCCESS -> Success
FAILED -> Failed
CANCELED -> Canceled
*/

好了,下面我们停下来思考一下,以上这些代码都解决了哪些问题,为什么需要两个转换函数,有没有更好的解决方式?

问题分析

为了完成这个需求,上述代码做了以下几件事:

  1. 后端状态码到前端状态的转换(1,2,3,4,5 -> PENDING, RUNNING, SUCCESS, FAILED, CANCELED)

  2. 前端状态字面量到展示字符串的转换(PENDING, RUNNING, SUCCESS, FAILED, CANCELED -> Pending, Running, Success, Failed, Canceled)

对于第一点,可以使用枚举类型来实现,这样就不需要手动维护状态码和状态字面量之间的映射关系了。

对于第二点,原本的实现是将全大写的状态转换为首字母大写的形式,这种转换方式比较简单,但实际业务中,可能会有更复杂的需求,比如用户希望看到不同的展示字符串(例如将RUNNING显示为In progress)。因此,使用一个映射表来处理这种转换会更加灵活。

优化后的代码

我们可以使用 TypeScript 的枚举类型来简化代码。首先定义一个枚举来表示 Job 状态:

enum JobStatus {PENDING = 1,RUNNING = 2,SUCCESS = 3,FAILED = 4,CANCELED = 5,
}

这样就可以省去第一个转换函数mapJobStatus,因为枚举本身就提供了状态码到状态字面量的映射,可以直接使用这个枚举来定义 Job 接口:

interface Job {id: string;name: string;status: JobStatus; // 使用枚举类型
}

接下来,重写getJobDisplayName, 这里使用typescript的Record类型来创建一个映射表(Record类型相当于一个键值对的映射,只不过键和值都是类型化的),将枚举值映射到展示字符串,与原本的实现方式相比,这种方式更加简洁易维护。

const getJobDisplayName: Record<JobStatus, string> = {[JobStatus.PENDING]: 'Pending',[JobStatus.RUNNING]: 'In progress',[JobStatus.SUCCESS]: 'Success',[JobStatus.FAILED]: 'Failed',[JobStatus.CANCELED]: 'Canceled',
};

最后是调用代码,如下:

const jobs = [{ id: '1', name: 'Job 1', status: 1 },{ id: '2', name: 'Job 2', status: 2 },{ id: '3', name: 'Job 3', status: 3 },{ id: '4', name: 'Job 4', status: 4 },{ id: '5', name: 'Job 5', status: 5 },
];jobs.forEach((job) => {console.log(`Job ID: ${job.id}, Name: ${job.name}, Status: ${getJobDisplayName[job.status as JobStatus]}`);
});

使用枚举类型的好处是:

  1. 可读性:枚举提供了更清晰的语义,

  2. 类型安全:TypeScript 的枚举类型可以确保状态值的合法性,避免了手动维护映射关系的错误。

  3. 简化代码:减少了转换函数的数量,使代码更简洁

  4. 易于维护:如果需要添加新的状态,只需在枚举中添加即可,不需要修改多个地方。

有没有更好的实现方式?很想听听大家的想法,欢迎留言讨论。

文章转载自:前端风云志

原文链接:TypeScript枚举类型应用:前后端状态码映射的最简方案 - 前端风云志 - 博客园

体验地址:JNPF快速开发平台

http://www.dtcms.com/a/279913.html

相关文章:

  • 深入学习前端 Proxy 和 Reflect:现代 JavaScript 元编程核心
  • Java并发编程之线程池详解
  • openGL学习(Shader)
  • 【面板数据】全国地级市逐日空气质量指数AQI数据集(2013-2024年)
  • 代码随想录算法训练营第四十九天|单调栈part2
  • Java强化:IO流
  • 正则表达式替换中使用 g<0> 引用整个匹配的内容
  • vim扩展与 neovim
  • IOS开发者账号如何添加 uuid 原创
  • Doris
  • 20250714--长连接应用中ORA-04061: existing state of has been invalidated
  • 迪拜金融市场交易量激增,中阿资本合作深化——阿联酋交易所系统解决方案全景解析
  • Transformer江湖录 第七章:江湖新篇 - Transformer的现代演化
  • FilterRegistationBean报错does not have type parameters。idea启动日志无明显报错提示冲突 kaki的博客
  • 力扣-25.K个一组翻转链表
  • 多线程进阶——线程安全的集合类
  • B站自动回复工具(破解)
  • Linux多进程
  • 国产IP摄像头存在隐蔽后门,攻击者可获取Root权限
  • 知识点2:MCP:python-sdk 核心概念
  • 丑团-h5-Mtgsig算法-分析
  • 技能升级--二分例题
  • 2025年大数据、建模与智能计算国际会议(ICBDMIC 2025)
  • 指针和数组(二)
  • AI 临床医学课题【总结】
  • Vue2 day08-10(智慧商城)
  • 应用系统报错:com.highgo.jdbc.util.PSQLException:bad value for long(APP)
  • DOM事件绑定时机:解决脚本提前加载导致的绑定失败
  • git modules
  • 8.6 Rag-基础工具介绍(开源工具)