如何在 TypeScript 中将字符串转换为枚举:分步指南
\n\n您是否遇到过 API 返回字符串,而您的 TypeScript 模型通过枚举严格类型化的情况?或者,您可能从 localStorage 获取值,并希望安全地将其转换为枚举?如果是这样,那么您来对地方了。在本文中,我们将探讨如何在 TypeScript 中将字符串转换为枚举——从简单解决方案到带有错误处理的高级技术。
这个主题是 Stack Overflow 上最热门的话题之一(成千上万的浏览量!),这并非没有原因。即使是经验丰富的开发人员,在安全地将字符串转换为枚举时也常常感到困惑。让我们来逐一理清。
\n\n什么是 TypeScript 中的枚举以及为什么要转换它?
\n\n枚举是 TypeScript 的一个强大工具,它允许您定义一组命名常量。您不必使用像 'active' 或 'pending' 这样的“魔法字符串”,而是定义枚举并使用类型化的值。但问题在于:来自外部来源(API、表单、配置文件)的数据通常以普通字符串的形式出现。这就引出了一个问题:如何安全且优雅地将字符串转换为 TypeScript 枚举?
// 枚举示例\nenum Status {\n Active = 'active',\n Inactive = 'inactive',\n Pending = 'pending'\n}\n\n// 来自 API 的字符串\nconst apiStatus: string = 'active';\n// 如何得到 Status.Active? 🤔\n\n方法 1:直接类型断言
\n\n这是最简单但也最危险的方法。您只是告诉 TypeScript:“相信我,这是正确的值。”
\n\nconst status = apiStatus as Status;\n// 或者\nconst status = <Status>apiStatus;\n\n优点: 代码最少。 缺点: 如果字符串不匹配枚举中的任何值,您将得到 undefined 而没有任何警告。TypeScript 不会抛出错误,您只会在运行时发现问题,当某些东西崩溃时。
只有在您绝对确定数据来源的情况下,才应使用此方法。对于生产环境——不推荐。
\n\n方法 2:使用自定义工具函数
\n\n这是在简单性和安全性之间的黄金平衡点。让我们编写一个函数,它接受一个字符串并检查该值是否存在于枚举中。
\n\nfunction stringToEnum<T>(value: string, enumObject: T): T[keyof T] | undefined {\n // 检查值是否在枚举中\n const enumValues = Object.values(enumObject) as string[];\n if (enumValues.includes(value)) {\n return value as unknown as T[keyof T];\n }\n return undefined;\n}\n\n// 使用\nconst status = stringToEnum(apiStatus, Status);\nif (status) {\n console.log(status); // Status.Active\n} else {\n console.error('无效的状态值');\n}\n\n这个函数安全地将字符串转换为 TypeScript 枚举。如果未找到该值,它返回 undefined,您可以处理这种情况。注意泛型 <T>——它使该函数适用于任何枚举。
方法 3:抛出错误的严格方法
\n\n有时 undefined 并不是您想要的。最好显式地抛出一个错误,以便快速发现问题。
function stringToEnumStrict<T>(value: string, enumObject: T): T[keyof T] {\n const enumValues = Object.values(enumObject) as string[];\n if (enumValues.includes(value)) {\n return value as unknown as T[keyof T];\n }\n throw new Error(`值 "${value}" 在枚举中未找到`);\n}\n\n// 使用\ntry {\n const status = stringToEnumStrict(apiStatus, Status);\n // 使用 status 进行操作\n} catch (error) {\n console.error(error.message);\n // 将错误记录到 Sentry 或其他监控系统\n}