扩展类型包括:类型别名、枚举、接口、类
枚举就是一个个的罗列,映射

枚举通常用于约束某个变量的取值范围。字面量和联合类型配合使用,也可以达到同样目标,但是有问题。

字面量类型的问题

  • 在类型约束位置,会产生重复代码。可以使用类型别名解决该问题。
  • 逻辑含义和真实的值(帅哥/美女, 男/女)产生了混淆,会导致当修改真实值的时候,产生大量修改。
    • 就是说因为你是字面量,在多处写了字面量,到时修改真实值时,就会产生大量修改
  • 字面量类型不会进入到编译结果(这些字面量类型信息直接丢失了)

所以才衍生出了枚举类型

枚举类型的使用

如何定义一个枚举

  1. enum meijuname{
  2. 枚举字段1 = 1,//左边是逻辑名称,右边是真实值
  3. 枚举字段2 = 2,
  4. }
  5. let gender1: Gender = Gender.male;
  6. let gender2: Gender = Gender.female;

枚举的好处:

  1. 使用的是逻辑名称
  2. tsc后会进入编译结果中,这就很恐怖很nb了,利用的是IIFE&&全局变量—对象.属性名

枚举的规则:

  • 枚举的字段可以是字符串或数字
  • 数字枚举的值会自动自增(默认从0开始),如果中间有个值跳跃了,后面的会接着跳跃的值继续自增
  • 被数字枚举约束的变量,可以直接赋值,不会报错,但这就会留下隐患
  • 数字枚举 和 字符串枚举 的编译结果有差异! ```javascript var Gender; (function (Gender) { Gender[“male”] = “\u7537”; Gender[“female”] = “\u5973”; })(Gender || (Gender = {})); let gender1 = Gender.male; let gender2 = Gender.female; console.log(gender1, gender2); function printGenders() { const vals = Object.values(Gender); vals.forEach(v => console.log(v)); } var Level; (function (Level) { Level[Level[“level1”] = 2] = “level1”; Level[Level[“level2”] = 3] = “level2”; Level[Level[“level3”] = 4] = “level3”; })(Level || (Level = {})); /**
    • 相当于是编译成为了
    • {
    • level1: 2,
    • level2: 3,
    • level3: 4,
    • 2:’level1’,
    • 3:’level2’,
    • 4:’level3’,
    • } */ let level1 = Level.level1; let level2 = Level.level2; let level3 = Level.level3; level3 = 8; console.log(level1, level2, level3);
  1. <a name="tygeS"></a>
  2. ## 枚举的最佳实践
  3. 1. 尽量**不要在**一个枚举中**同时出现** 字符串字段和数字字段
  4. 1. 尽量**使用枚举字段的名称**,而不使用真实的值
  5. <a name="ZzynG"></a>
  6. # 利用枚举类型改进扑克牌程序
  7. ```typescript
  8. //一副牌
  9. type Deck = NormalCard[];
  10. //牌号
  11. enum Mark {
  12. A = 'A',
  13. two = '2',
  14. three = '3',
  15. four = '4',
  16. five = '5',
  17. six = '6',
  18. seven = '7',
  19. eight = '8',
  20. nine = '9',
  21. ten = '10',
  22. eleven = 'J',
  23. twelve = 'Q',
  24. thirteen = 'K',
  25. }
  26. //花色
  27. enum Color {
  28. heart = '红心♥️',
  29. spade = '♠️',
  30. diamond = '♦️',
  31. club = '♣️',
  32. };
  33. //一张牌
  34. type NormalCard = {
  35. // color: string,//花色, 进行一下限制, 因为总共就四种
  36. color: Color,
  37. mark: Mark,//序号
  38. };
  39. function createDeck(): Deck{
  40. const deck: Deck = [];
  41. const marks = Object.values(Mark);
  42. const colors = Object.values(Color);
  43. for(const m of marks){
  44. for(const c of colors){
  45. deck.push({
  46. color: c,
  47. mark: m
  48. })
  49. }
  50. }
  51. return deck;
  52. }
  53. function printDeck(deck: Deck){
  54. deck.forEach((card, i)=>{
  55. let str = card.color + ' ' +card.mark;
  56. console.log(str);
  57. if((i+1)%4 === 0){
  58. console.log('\n');
  59. }
  60. });
  61. }
  62. const deck = createDeck();
  63. printDeck(deck);

扩展知识:位枚举(枚举的位运算)

主要是针对 数字枚举

  1. //1. 如何组合权限, 利用 按位或 运算, 有 1 出 1
  2. let p = Permission.Read | Permission.Write;//0011
  3. console.log(p);//3
  4. //2. 如何判断一个权限是否拥有某个权限, 利用 按位与 后, 判断是否与sonPer相等
  5. //比如判断0101是否含有0001权限
  6. function hasPermission(target: Permission, sonPer: Permission) {
  7. return (target & sonPer) === sonPer;
  8. }
  9. console.log(hasPermission(p, Permission.Write));//看p是否有write权限
  10. //3. 如何删除某个权限, 利用按位疑惑,相同为0不同为1
  11. p = p ^ Permission.Write;
  12. console.log(p);//1
  1. 组合权限:按位或,A | B
  2. A权限是否拥有B权限:(A & B) === B
  3. 删除权限:A ^ B