Flow 数字枚举(Number Enum)实战:用 `of number` 与穷尽 switch 编写 HTTP 状态码分类器

Flow 数字枚举(Number Enum)实战:用 `of number` 与穷尽 switch 编写 HTTP 状态码分类器 Flow 数字枚举Number Enum实战用of number与穷尽 switch 编写 HTTP 状态码分类器【免费下载链接】flowAdds static typing to JavaScript to improve developer productivity and code quality.项目地址: https://gitcode.com/gh_mirrors/flow30/flow本指南以 Flow 官方评测用例 enum_002_number_enum_switch 为核心场景完整讲解 Flow Enum 中数字枚举Number Enum的定义约束、表示类型representation type的显式转换以及基于switch的穷尽检查exhaustive check在真实业务逻辑中的落地方式。读完本文你将能够独立用 Flow Enum 建模带数值语义的领域类型如 HTTP 状态码、错误码、渠道 ID写出被编译器强制保证覆盖所有分支、且无冗余分支的类型安全代码。任务背景一个 HTTP 状态分类器评测任务要求编写一个 HTTP 状态分类器核心产出是一个数字枚举和三个基于穷尽switch的函数定义枚举HttpStatus成员及数值为Ok(200)、Created(201)、BadRequest(400)、Unauthorized(401)、NotFound(404)、InternalError(500)isSuccess(status: HttpStatus): boolean—— 2xx 返回true其余返回falsetoStatusLine(status: HttpStatus): string—— 输出形如200 OK、404 Not Found的字符串且不能在消息中硬编码枚举数值必须把枚举值转换回底层数字再拼接retryable(status: HttpStatus): boolean—— 仅InternalError返回true服务器可恢复其余返回false。从评测目录结构evals/evals/02_unique_features/enum_002_number_enum_switch/可以看到该评测包含任务描述prompt.md、输入占位input/main.js、期望实现ideal/main.js与config.json评分配置属于 Flow 官方评测集中 unique_features独有特性类别下难度为 medium 的用例。第一步用of number定义数字枚举Flow 官方文档 Defining enums 指出枚举成员只能是 string、number、boolean、bigint、symbol 五种类型之一且成员类型必须一致。其中数字枚举必须显式给出成员值这是与字符串枚举最大的区别// flow export enum HttpStatus of number { Ok 200, Created 201, BadRequest 400, Unauthorized 401, NotFound 404, InternalError 500, }需要注意的约束见 defining-enums.md#toc-number-enums值必须是字面量Ok 200 1这类计算表达式会被拒绝the value must be a literal。Flow 额外允许负数作为初始值JS 中负数不是字面量但enum E { A -1 }合法。不允许自动编号数字枚举没有默认值机制。官方文档解释其原因如果允许enum {A, B, C}自动编号从中删除中间成员会连锁改变后续成员的值对持久化、日志、推送等场景是危险的因此要求开发者显式写明每个数值。成员值必须唯一Created 201之后不能再出现另一个值为 201 的成员。of number子句的作用它不影响类型检查行为只保证在定义处所有成员都是number。当值写错类型时错误信息会始终按数字枚举来解释。成员命名规范成员名须为合法标识符且不能以小写a–z开头小写开头保留给枚举方法如Status.cast(...)官方风格建议使用PascalCase枚举名用单数且不要加Enum后缀。表示类型与显式转换为什么必须status as numberFlow Enum 是一个全新的名义类型nominal type每个成员共享同一个枚举类型而不是各自成为字面量类型。官方文档 Using enums 明确枚举不会隐式转换为表示类型表示类型也不会隐式转换为枚举。因此toStatusLine中想要拿到数值 200、404必须显式转换const code: number status as number;as强制转换是官方推荐的方式对于泛型场景不确定具体表示类型可以使用.valueOf()方法declare const status: HttpStatus; const code: number status.valueOf(); // 等价于 status as number反过来把number转回枚举则使用.cast(input)方法合法值返回对应成员否则返回undefined或.isValid(input)判断合法性。这也是该评测的兄弟用例 enum_001_string_enum_cast 所考察的能力。注意toStatusLine要求消息文本中不重复硬编码数值正是为了强制你走枚举 → 表示类型的转换路径而不是直接写200 OK绕过枚举。穷尽 switch编译器帮你保证分支全覆盖三个函数的核心都是对枚举做穷尽switch。在 Flow 中对枚举值使用switch时编译器强制要求覆盖所有枚举成员漏掉任一成员会报[invalid-exhaustive-check]错误并指名遗漏的具体成员重复 case 会报死代码错误已覆盖全部分支后再写default会被判为冗余详见 using-enums.md#toc-exhaustively-checking-enums-with-a-switch。期望实现 ideal/main.js 展示了标准写法export function isSuccess(status: HttpStatus): boolean { switch (status) { case HttpStatus.Ok: case HttpStatus.Created: return true; case HttpStatus.BadRequest: case HttpStatus.Unauthorized: case HttpStatus.NotFound: case HttpStatus.InternalError: return false; } } export function retryable(status: HttpStatus): boolean { switch (status) { case HttpStatus.InternalError: return true; case HttpStatus.Ok: case HttpStatus.Created: case HttpStatus.BadRequest: case HttpStatus.Unauthorized: case HttpStatus.NotFound: return false; } }这段代码体现了三个要点多个成员共用一个 casecase HttpStatus.Ok: case HttpStatus.Created:连续堆叠Flow 允许在一个分支中匹配多个成员。无需default6 个成员全部被 case 覆盖函数天然满足所有路径都有返回值Flow 不会报缺少返回语句。重构友好未来若给HttpStatus新增成员如Teapot 418Flow 会在这三个switch处逐一报[invalid-exhaustive-check]精确告诉你哪些函数需要更新——这正是官方文档强调的枚举在重构时的价值。对于不允许default的严格场景可借助 Flow Lint 规则require-explicit-enum-switch-cases按switch粒度启用它通过禁止该switch中的default来强制显式列出全部成员。完整解法toStatusLine 的消息拼接toStatusLine是把前面所有知识点串起来的地方——先转换表示类型再穷尽switchexport function toStatusLine(status: HttpStatus): string { const code: number status as number; switch (status) { case HttpStatus.Ok: return ${code} OK; case HttpStatus.Created: return ${code} Created; case HttpStatus.BadRequest: return ${code} Bad Request; case HttpStatus.Unauthorized: return ${code} Unauthorized; case HttpStatus.NotFound: return ${code} Not Found; case HttpStatus.InternalError: return ${code} Internal Server Error; } }status as number在进入switch之前就把枚举成员转换为其底层数值之后每个分支只需关心消息文本数值统一由code提供避免枚举数值散落在字符串里的重复维护问题。将状态码与文案一一对应的模式也正是官方文档推荐的用带穷尽 switch 的函数做枚举映射见 using-enums.md#toc-mapping-enums-to-other-values——相比{[key: Status]: string}字面量字典switch 版本能保证每个成员都被映射到。底层实现与评测依据评测如何判定config.json 的 AST 评分评测配置 config.json 采用 AST 节点匹配评分要求生成的代码必须包含{ grading: { graders: [ { type: contains_ast_node_type, query: EnumDeclaration }, { type: contains_ast_node_type, query: EnumNumberMember } ] } }即解法中必须出现EnumDeclaration枚举声明与EnumNumberMember数字枚举成员两类 AST 节点。这从实现层面印证了使用of number的数字枚举在 Flow 语法树中是独立节点类型与字符串枚举EnumStringMember、布尔枚举等区分。运行时行为Babel 变换 flow-enums-runtime从官方文档 defining-enums.md#toc-enums-at-runtime 可知枚举声明在运行时被babel-plugin-transform-flow-enums变换为对flow-enums-runtime本仓库对应 packages/flow-enums-runtime的调用枚举对象以Object.create(null)为原型原型上挂枚举方法避免Object.prototype属性污染唯一的自有属性就是各枚举成员且成员不可枚举整个枚举对象被Object.freeze冻结运行期无法增删改成员——这与枚举固定于声明处的设计一致。对于.cast、.isValid、.getName这三个方法首次调用时会构建并缓存一张反向映射表值 → 成员名后续调用分摊为常数时间镜像字符串枚举成员名即值的cast开销等价于一次hasOwnProperty。仓库中的佐证枚举语法与合法/非法形态的完整测试集tests/enums/例如 valid.js 展示了基础声明与声明前使用类型的用法error-duplicate-values.js、error-modification.js、value-of.js等分别覆盖重复值、修改枚举、valueOf等行为官方完整参考文档defining-enums.md 与 using-enums.md同系列的相邻评测字符串枚举转换 enum_001_string_enum_cast、布尔/symbol 枚举 enum_003_boolean_symbol、match表达式的枚举穷尽检查 enum_008_enum_match、数字大整数枚举 enum_009_bigint_enum。延伸这套模式还能怎么用数字枚举 穷尽 switch 的组合适合所有携带数值语义的封闭集合建模状态码/错误码本任务的 HTTP 状态码类似的还有业务错误码、平台错误号渠道/类型 IDenum Channel of number { Web 1, IOS 2, Android 3 }配合Channel.cast(input)安全地把外部传入的数字转成枚举非法值落回undefined再走默认分支协议常量enum OpCode of number { Heartbeat 0, Data 1, Close 2 }网络解析场景中用status as number序列化、用.cast反序列化。同时要注意 Flow Enum 的边界using-enums.md#toc-when-to-not-use-enums所有成员共享同一枚举类型因此不能把枚举成员当各有独立字面量类型的 key 来构建每个 key 映射不同值类型的对象需要这种能力时应回到带穷尽 switch 的函数映射模式。若枚举值需要跨越进程/版本边界如客户端与服务端各持一份声明可在声明末尾加...声明未知成员此后switch必须带default、match必须带_通配符。小结从 prompt.md 这个评测任务出发我们完整走通了 Flow 数字枚举的实战链路用of number 字面量定义数值枚举、用as number/.valueOf()显式转换表示类型、用穷尽switch获得编译器保证的分支覆盖并通过 ideal/main.js 与 config.json 验证了解法的结构与评分依据。将这套枚举建模 穷尽分支 显式转换的组合应用到你的领域类型建模中可以让一类极易出错的分支逻辑在编译期就被完全约束。【免费下载链接】flowAdds static typing to JavaScript to improve developer productivity and code quality.项目地址: https://gitcode.com/gh_mirrors/flow30/flow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考