扩展类型-枚举

  1. 扩展类型:类型别名、枚举、接口、类

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

字面量类型的问题

  1. 在类型约束位置,会产生重复代码 (可以使用类型别名解决该问题)

  2. 逻辑含义和真实的值产生了混淆,会导致当修改真实值的时候,产生大量的修改 (eg: type gender = “男” | “女”,之后修改 “男” => 帅哥,需要修改大量代码)

  3. 字面量类型不会进入到编译结果;

枚举

枚举的规则

  1. 枚举的字段值可以是 字符串数字

  2. 数字枚举的值会 自动自增

  3. 被数字枚举约束的变量,可以直接赋值为数字;

  4. 数字枚举的编译结果 和 字符串枚举有差异;

常量枚举

  1. 加上 const 就是常量枚举,不会侵入编译结果;

  2. 常量枚举只能单向获取值;

TypeScript
TypeScript
const enum PostStatus {
    Draft = 6,
    Unpublished, // => 7
    Published = 'aaa',
}
console.log(PostStatus['Draft']); // 6
console.log(PostStatus['Published']); // aaa
// 编译之后,会把枚举移除掉
console.log(6 /* PostStatus['Draft'] */); // 6
console.log("aaa" /* PostStatus['Published'] */); // aaa

数字/字符串枚举

  1. 数字枚举可双向获取枚举值

  2. 数字枚举,枚举值自动基于前一个值自增

TypeScript
TypeScript
enum PostStatus {
    Draft = 6,
    Unpublished, // => 7
    Published = 'aaa',
}

console.log(PostStatus[6]); // Draft => 使用索引器的方式获取 key
console.log(PostStatus['Draft']); // 6
console.log(PostStatus['aaa']); // undefined
console.log(PostStatus['Published']); // aaa
// 编译之后,数字枚举会形成双向的健值对对象,不会移除枚举
var PostStatus;
(function (PostStatus) {
    PostStatus[PostStatus["Draft"] = 6] = "Draft";
    PostStatus[PostStatus["Unpublished"] = 7] = "Unpublished";
    PostStatus["Published"] = "aaa";
})(PostStatus || (PostStatus = {}));

console.log(PostStatus[6]); // Draft => 使用索引器的方式获取 key
console.log(PostStatus['Draft']); // 6
console.log(PostStatus['aaa']); // undefined
console.log(PostStatus['Published']); // aaa

最佳实践

  1. 尽量不要在一个枚举中既出现字符串字段,又出现数字字段;

  2. 使用枚举时,尽量使用枚举字段的名称,而不使用真实的值;

案例

位枚举(枚举的位运算)

  1. 针对的数字枚举;

  2. 位运算:两个数字换算成二进制后进行的运算;

enum Permission {
    Read = 1,   // 0001
    Write = 2,  // 0010
    Create = 4, // 0100
    Delete = 8  // 1000
}

// 1. 权限组合
let p: Permission = Permission.Read | Permission.Write; // 0001 | 0010 => 0011

// 2. 判断是否拥有某个权限
function hasPermission(target: Permission, per: Permission) {
    // (0011 & 0010) === 0010,存在 0010 这个权限
    return (target & per) === per;
}

// 3. 如何删除某个权限
p = p ^ Permission.Write; // 0011 ^ 0010 => 0001,删除了 0010 这个权限

console.log(hasPermission(p, Permission.Write));

使用枚举优化扑克牌程序

enum Color {
    heart = "♥",
    spade = "♠",
    club = "♣",
    diamond = "♦"
}
enum Mark {
    one = "A",
    two = "2",
    three = "3",
    four = "4",
    five = "5",
    six = "6",
    seven = "7",
    eight = "8",
    nine = "9",
    ten = "10",
    eleven = "J",
    twelve = "Q",
    king = "K"
}
type NormalCard = {
    color: Color
    mark: Mark
}
type Deck = NormalCard[]


function createDeck(): Deck {
    const deck: Deck = [];
    const marks = Object.values(Mark)
    const colors = Object.values(Color)
    for (const m of marks) {
        for (const c of colors) {
            deck.push({ color: c, mark: m });
        }
    }
    return deck;
}

function printDeck(deck: Deck) {
    let result = "\n";
    deck.forEach((card, i) => {
        let str = card.color + card.mark;
        result += str + "\t";
        if ((i + 1) % 4 === 0) {
            result += "\n";
        }
    })
    console.log(result);
}

const deck = createDeck();
printDeck(deck);
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 扩展类型-枚举
  2. 2. 字面量类型的问题
  3. 3. 枚举
    1. 3.1. 枚举的规则
    2. 3.2. 常量枚举
    3. 3.3. 数字/字符串枚举
  4. 4. 最佳实践
  5. 5. 案例
    1. 5.1. 位枚举(枚举的位运算)
    2. 5.2. 使用枚举优化扑克牌程序