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

阮一峰《TypeScript 教程》学习笔记——Enum 类型

1. 一段话总结

Enum(枚举) 是 TypeScript 特有的数据结构与类型(JavaScript 无此类型),核心作用是将相关常量聚合管理,兼具类型语义运行时值(编译后转为 JavaScript 对象,const enum 编译后会替换为常量值以优化性能);主要分为数值Enum(默认从0递增,支持显式赋值、计算式,存在反向映射)与字符串Enum(需显式赋值,不支持表达式,无反向映射);支持同名Enum自动合并(需满足“仅一个首成员可省略初始值、无同名成员、同const/非const”);可通过keyof typeof Enum获取成员名联合类型;其功能可部分被as const断言(原生对象+只读)或联合类型替代,官方建议谨慎使用以避免冗余编译产物。


2. 思维导图

在这里插入图片描述


3. 详细总结

一、Enum 类型基础

  1. 核心定位
    Enum 是 TypeScript 新增的“类型+值”双属性结构,JavaScript 无此类型:

    • 类型语义:用于约束变量取值范围(如let c:Color = Color.Red);
    • 运行时值:编译后转为 JavaScript 对象(非const enum),如:
      // 编译前(非const enum)
      enum Color { Red, Green }
      // 编译后
      let Color = { Red: 0, Green: 1 };
      
    • const enum 优化:加const修饰后,编译时会将成员直接替换为对应值(无对象生成),提升性能:
      // 编译前(const enum)
      const enum Color { Red, Green }
      const x = Color.Red;
      // 编译后
      const x = 0 /* Color.Red */;
      
  2. 适用场景
    当“成员名的语义价值”高于“具体值”时(如状态标识、操作类型),示例:

    enum Operator { ADD, SUB, MUL, DIV } // 四则运算标识,值无关紧要
    
  3. 替代方案
    因 Enum 会生成冗余编译产物,官方建议优先使用原生方案:

    替代方案语法示例优势
    as const断言const Bar = { A:0, B:1 } as const原生JS对象,只读不可改
    联合类型`type Dir = ‘Up’‘Down’`

二、Enum 成员值规则

Enum 成员值分为“数值型”与“字符串型”,规则差异显著,具体对比如下:

对比维度数值Enum字符串Enum
默认赋值未显式赋值时从0递增必须全显式赋值(否则报错)
值类型支持整数、小数(不支持Bigint)、计算式字符串(不支持表达式,如['a'].join('')报错)
反向映射支持(通过值获取成员名)不支持
类型兼容性可赋值为number(如let c:number = Color.Red不可赋值为原生字符串(如let s:MyEnum = 'One'报错)
示例enum Color { Red=7, Green, Blue=1<<3 }enum Dir { Up='UP', Down='DOWN' }

补充说明:

  • 计算式支持:数值Enum成员可使用计算式(如位运算、函数返回值),示例:
    enum Permission { UserRead = 1 << 8 } // 256
    
  • 成员值唯一性:数值Enum允许成员值相同(如Red=0, Green=0),但会失去区分意义,不推荐。

三、同名Enum合并

多个同名Enum会自动合并,需满足3条规则:

  1. 初始值规则:仅一个Enum的首成员可省略初始值(否则报错,避免递增歧义);
  2. 成员名规则:无同名成员(如两个Enum都有B成员会报错);
  3. 类型一致性规则:所有Enum需同为const enum或同为非const enum(混合使用报错)。

示例(合法合并):

enum Foo { A } // 首成员省略初始值(A=0)
enum Foo { B=1 } // 合并后Foo={A:0, B:1}

四、keyof 运算符与反向映射

  1. keyof 运算符
    用于获取Enum的成员名联合类型,需配合typeof(否则keyof Enum等同于keyof number,返回数值原生方法名):

    enum MyEnum { A='a', B='b' }
    type MemberNames = keyof typeof MyEnum; // 'A'|'B'
    
  2. 反向映射(仅数值Enum)

    • 定义:通过成员值反向获取成员名(如Weekdays[3] → ‘Wednesday’);
    • 原理:数值Enum编译后会生成两组赋值Enum[成员名]=值+Enum[值]=成员名),示例:
      // 编译前(数值Enum)
      enum Weekdays { Monday=1, Tuesday=2 }
      // 编译后(关键代码)
      Weekdays["Monday"] = 1;
      Weekdays[1] = "Monday"; // 反向映射的核心
      
    • 限制:字符串Enum编译后仅生成Enum[成员名]=值,无反向映射。

五、使用注意事项

  1. 谨慎使用Enum:Enum并非TS“类型增强”核心功能,编译后会生成冗余对象(const enum可避免),优先用as const或联合类型替代;
  2. 避免同名冲突:Enum编译后为全局对象,不可与其他变量(函数、类、对象)同名;
  3. 数值Enum类型宽松:数值Enum作为类型时,允许赋值为任意number(如foo(33)foo(noYes:Bool)不报错),需自行确保取值合法性。

4. 关键问题

问题1:Enum 与 as const 断言的核心差异是什么?为何官方建议优先考虑 as const

答案
两者核心差异体现在“语言原生性”与“编译产物”:

  1. Enum:TS特有类型,编译后生成冗余JavaScript对象(非const Enum),虽兼具类型与值,但增加代码体积;支持反向映射(数值Enum)、同名合并等特有功能,语义更明确但灵活性较低。
  2. as const:基于JavaScript原生对象,通过断言将对象转为“只读+值类型”,无额外编译产物;仅具备“只读常量聚合”功能,不支持反向映射、合并,但更符合JS生态,无冗余代码。

官方建议优先用as const的原因是:Enum会引入非JS原生的冗余结构,而as const依托原生对象,既能实现“常量聚合+只读”,又避免编译后多余代码,更符合TS“增强JS而非替代JS”的定位。

问题2:为何反向映射仅存在于数值Enum,字符串Enum不支持?请从编译原理角度解释。

答案
反向映射的核心是“通过成员值获取成员名”,其可行性取决于Enum编译后的赋值逻辑:

  • 数值Enum:编译后会生成两组赋值语句:第一组为“成员名→值”(如Weekdays["Monday"] = 1),第二组为“值→成员名”(如Weekdays[1] = "Monday"),两组赋值共同构成反向映射的基础。
  • 字符串Enum:编译后仅生成一组赋值语句(“成员名→值”,如Dir["Up"] = "UP"),无“值→成员名”的反向赋值,因此无法通过字符串值获取成员名,即不支持反向映射。

简言之,反向映射的本质是编译后的双向赋值,字符串Enum缺少反向赋值步骤,故无此功能。

问题3:字符串Enum相比数值Enum有哪些特殊限制?这些限制的原因是什么?

答案
字符串Enum有3点特殊限制,均与“值的确定性”和“类型安全性”相关:

  1. 必须全显式赋值
    原因:数值Enum可通过“递增”默认生成值(如Red=0, Green=1),但字符串无天然递增规则,若省略赋值会导致值不确定,因此TS强制要求全显式赋值。

  2. 成员值不支持表达式
    原因:表达式(如['a','b'].join(''))的结果需运行时计算,可能导致值不可预测;而字符串Enum的核心场景是“固定字符串常量”,TS通过禁止表达式确保值的确定性。

  3. 不可赋值为原生字符串
    原因:数值Enum本质是number的子类型(可赋值为number),但字符串Enum是独立类型(非string子类型),TS通过此限制强化类型语义,避免“Enum类型”与“原生字符串”混用导致的类型模糊(如let s:MyEnum = 'One'报错,确保s仅能取Enum成员)。

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

相关文章:

  • 人工只能综合项目开发8---手势识别data_processing
  • C primer plus (第六版)第十一章 编程练习第13题
  • 网站被k申述泉州专业网站建设公司
  • FLUMINER福禄T3 115T挖矿机深度评测:智能管理与高效性能如何平衡?
  • 怎么调网站兼容性公益网站怎么做
  • 压缩与缓存调优实战指南:从0到1根治性能瓶颈(四)
  • 嵌入式软件架构--显示界面架构(工厂流水线模型,HOME界面,命令界面)
  • Ubuntu20.04 + QT5.14.2 + Android23的开发平台搭建总结
  • 【思维链条CoT与React模式深度解析】AI智能体的核心推理框架
  • svchost第一个是rpcss第二个是termsvcs第三个是NetworkService第四个是LocalService第五个是netsvcs----备忘
  • 餐饮网站模板免费下载jetpack wordpress
  • Hadoop High Availability 简介
  • Tier 1 供应商EDI对接:Forvia EDI需求分析
  • 2025最新策略答案引擎优化(AEO):在AI搜索引擎中获得更多曝光
  • SpringAI Redis RAG 搜索
  • 服务器和域名都有了 怎么做网站网站seo诊断分析报告
  • SpringBoot的Web开发
  • 基于springboot的大创管理系统开发与设计
  • GitHub 热榜项目 - 日榜(2025-10-23)
  • RAG:让大模型“既懂又查”的智能系统
  • cms网站建设的优缺点wordpress两个站合并
  • 数据结构——B树及其基本操作
  • java.text.MessageFormat的用法
  • 公司网站怎么做分录平面设计怎么网上接单
  • Java爬虫性能优化:以喜马拉雅音频元数据抓取为例
  • 使用 Java 对 PDF 添加水印:提升文档安全与版权保护
  • CRMEB-PHP订单改价模块详解
  • 丽水 网站建设注册163免费邮箱
  • 网站建设微信开发怎么做订阅号
  • TypeScript Array(数组)