一、扩展类型
扩展类型:类型别名、枚举、接口、类。
枚举:通常用于约束某个变量的取值范围。
字面量和联合类型配合使用,也可以达到同样的目标。
二、字面量类型的问题
- 在类型约束位置,会产生重复代码。可以使用类型别名解决该问题;
- 逻辑含义和真实的值产生了混淆,会导致当修改真实值的时候,产生大量的修改;
- 字面量类型,不会进入编译结果。
三、枚举
1.如何定义一个枚举
enum 枚举名{
枚举字段1 = 值1,
枚举字段2 = 值2,
...
}
enum Sex { male = "男",female = "女"
}let sex: Sex
sex = Sex.maleconsole.log(sex); // 男
上面代码中,将枚举中的 male 改为 "帅哥" ,则输出 "帅哥" 。
枚举会出现在编译结果中,编译结果中表现为 对象 。
var Sex;
(function (Sex) {Sex["Male"] = "\u7537";Sex["Female"] = "\u5973";
})(Sex || (Sex = {}));
let sex;
sex = Sex.Male;
console.log(sex);
2.枚举的规则
- 枚举的 字段值 可以使用 字符串 或者 数字 ;
- 数字枚举的值会 自增 ,当第一个字段没有赋值时,默认为 0 ;
- 被数字枚举约束的变量,可以直接赋值为数字,可能会导致问题,不推荐;
- 数字枚举的编译结果 和 字符串的编译结果有差异;
enum Level { level1 = 2,level2,level3,
}let l: Level = Level.level2console.log(l); // 3
enum Level { level1,level2,level3,
}let l: Level = Level.level1console.log(l); // 0
数字枚举的编译结果:
var Level;
(function (Level) {Level[(Level["level1"] = 0)] = "level1";Level[(Level["level2"] = 1)] = "level2";Level[(Level["level3"] = 2)] = "level3";
})(Level || (Level = {}));
/*
{level1: 0,level2: 1,level3: 2,0:"level1",1:"level2",2:"level3"
}
*/
let l = Level.level1;
console.log(l);
因此循环遍历数字枚举时需要考虑到这点。
3.最佳实践
- 尽量不要在一个枚举中即出现字符串字段,又出现数字字段;
- 使用枚举时,尽量使用枚举字段的名称,而不使用真实的值;
四、位枚举(枚举的位运算)
位枚举针对数字枚举。
位运算:两个数字换算成二进制的运算。
// 位枚举
enum Permission { Read = 1, // 2^0 0001Write = 2, // 2^1 0010Create = 4, // 2^2 0100Delete = 8 // 2^3 1000
}// 1.如何组合权限:使用或运算
let p: Permission = Permission.Read | Permission.Write// 2.如何判断是否有权限:使用与运算
// let hasRead: boolean = (p & Permission.Read) === Permission.Read
function hasPermission(target: Permission, per: Permission) { return (target & per) === per
}
// 判断变量p是否拥有可读权限
console.log(hasPermission(p, Permission.Read)); // true// 3.如何删除某个权限:使用异或运算
p = p ^ Permission.Write
console.log(hasPermission(p, Permission.Write)); // false