TypeScript 枚举值存在性检查:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么需要检查 TypeScript 枚举值?一个实际案例

\n\n

想象一下:您正在使用 TypeScript 编写一个 Node.js 后端。客户端发送一个订单状态——字符串 "shipped"。您有一个包含以下选项的枚举 OrderStatus:Pending、Processing、Shipped、Delivered。但突然收到了 "CANCELLED" 或 "unknown"。该怎么办?正确做法是——检查 TypeScript 枚举中是否存在该值。

\n\n

这个问题是 Stack Overflow 上最常见的问题之一(数千次浏览)。这并不奇怪:TypeScript 中的枚举不仅仅是一组常量,而是一个包含数字和字符串变体的复杂结构。在本指南中,我们将介绍所有检查枚举值存在性的方法,从简单到高级,并附有代码示例和解释。

\n\n

无论您是刚开始学习 TypeScript,还是想加深理解,本文都适合您。让我们开始吧!

\n\n

什么是 TypeScript 枚举?快速入门

\n\n

枚举(Enum)是一种定义一组命名常量的方式。TypeScript 中有两种类型的枚举:

\n\n
    \n
  • 数字枚举——值会自动递增(0, 1, 2...)。
  • \n
  • 字符串枚举——每个成员都显式分配一个字符串。
  • \n
\n\n

数字枚举示例:

\n\n
enum Direction {\n    Up,    // 0\n    Down,  // 1\n    Left,  // 2\n    Right  // 3\n}
\n\n

字符串枚举示例:

\n\n
enum Status {\n    Active = "ACTIVE",\n    Inactive = "INACTIVE",\n    Pending = "PENDING"\n}
\n\n

为什么要检查值?因为来自外部(API、表单、数据库)的数据可能是任意的。不进行检查,您可能会得到 undefined 或运行时错误。

\n\n

方法 1. 经典方法:Object.values() + includes()

\n\n

最流行且可读性最高的方法是将枚举转换为值数组,然后使用 includes() 检查是否存在。

\n\n

对于字符串枚举:

\n\n
enum Color {\n    Red = "RED",\n    Green = "GREEN",\n    Blue = "BLUE"\n}\n\nfunction isColor(value: string): boolean {\n    return Object.values(Color).includes(value as Color);\n}\n\nconsole.log(isColor("RED"));    // true\nconsole.log(isColor("YELLOW")); // false
\n\n

对于数字枚举——有个小技巧!Object.values() 会返回反向映射(键和值)。因此需要只过滤数字:

\n\n
enum NumberEnum {\n    A = 1,\n    B = 2,\n    C = 3\n}\n\nfunction isNumberEnumValue(value: number): boolean {\n    return Object.values(NumberEnum).filter(v => typeof v === 'number').includes(value);\n}\n\nconsole.log(isNumberEnumValue(2)); // true\nconsole.log(isNumberEnumValue(5)); // false
\n\n

这种方法通用性强,但处理数字枚举时需要小心。优点:简单直观。缺点:需要记住进行过滤。

\n\n

方法 2. 类型守卫:通过枚举键进行检查

\n\n

如果您不仅需要检查值,还需要获得类型保证,请使用类型守卫。这种方法在处理 API 时特别有用,因为它可以帮助您缩小类型范围。

\n\n
enum UserRole {\n    Admin = "admin",\n    User = "user",\n    Guest = "guest"\n}\n\nfunction isUserRole(value: string): value is UserRole {\n    return Object.values(UserRole).includes(value as UserRole);\n}\n\nfunction processRole(role: string) {\n    if (isUserRole(role)) {\n        // TypeScript 知道 role 是 UserRole 类型\n        console.log(`角色: ${role}`);\n    } else {\n        console.log("未知角色");\n    }\n}\n\nprocessRole("admin"); // 角色: admin\nprocessRole("moderator"); // 未知角色
\n\n

这种方法提供了类型安全性,并减少了代码中的检查次数。我建议在严肃项目中使用。

\n\n

方法 3. 自定义辅助函数

博客

书籍推荐