扩展类型包括:类型别名、枚举、接口、类
枚举就是一个个的罗列,映射
枚举通常用于约束某个变量的取值范围。字面量和联合类型配合使用,也可以达到同样目标,但是有问题。
字面量类型的问题
- 在类型约束位置,会产生重复代码。可以使用类型别名解决该问题。
- 逻辑含义和真实的值(帅哥/美女, 男/女)产生了混淆,会导致当修改真实值的时候,产生大量修改。
- 就是说因为你是字面量,在多处写了字面量,到时修改真实值时,就会产生大量修改
- 字面量类型不会进入到编译结果(这些字面量类型信息直接丢失了)
枚举类型的使用
如何定义一个枚举
enum meijuname{枚举字段1 = 值1,//左边是逻辑名称,右边是真实值枚举字段2 = 值2,}let gender1: Gender = Gender.male;let gender2: Gender = Gender.female;
枚举的好处:
- 使用的是逻辑名称
- 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);
<a name="tygeS"></a>## 枚举的最佳实践1. 尽量**不要在**一个枚举中**同时出现** 字符串字段和数字字段1. 尽量**使用枚举字段的名称**,而不使用真实的值<a name="ZzynG"></a># 利用枚举类型改进扑克牌程序```typescript//一副牌type Deck = NormalCard[];//牌号enum Mark {A = 'A',two = '2',three = '3',four = '4',five = '5',six = '6',seven = '7',eight = '8',nine = '9',ten = '10',eleven = 'J',twelve = 'Q',thirteen = 'K',}//花色enum Color {heart = '红心♥️',spade = '♠️',diamond = '♦️',club = '♣️',};//一张牌type NormalCard = {// color: string,//花色, 进行一下限制, 因为总共就四种color: Color,mark: Mark,//序号};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){deck.forEach((card, i)=>{let str = card.color + ' ' +card.mark;console.log(str);if((i+1)%4 === 0){console.log('\n');}});}const deck = createDeck();printDeck(deck);
扩展知识:位枚举(枚举的位运算)
主要是针对 数字枚举
//1. 如何组合权限, 利用 按位或 运算, 有 1 出 1let p = Permission.Read | Permission.Write;//0011console.log(p);//3//2. 如何判断一个权限是否拥有某个权限, 利用 按位与 后, 判断是否与sonPer相等//比如判断0101是否含有0001权限function hasPermission(target: Permission, sonPer: Permission) {return (target & sonPer) === sonPer;}console.log(hasPermission(p, Permission.Write));//看p是否有write权限//3. 如何删除某个权限, 利用按位疑惑,相同为0不同为1p = p ^ Permission.Write;console.log(p);//1
- 组合权限:按位或,A | B
- A权限是否拥有B权限:(A & B) === B
- 删除权限:A ^ B
