TypeScript基础(二)扩展类型-枚举及其位运算

简介: TypeScript中的枚举(Enum)是一种数据类型,用于定义一组具有命名值的常量。枚举可以帮助我们在代码中使用更具有可读性和可维护性的常量。本文将介绍字面量类型的问题、类型别名的局限以及枚举的优缺点及示例详细说明枚举的用处,以及扩展知识枚举的位运算。

引言

TypeScript中的枚举(Enum)是一种数据类型,用于定义一组具有命名值的常量。枚举可以帮助我们在代码中使用更具有可读性和可维护性的常量。

本文将介绍字面量类型的问题、类型别名的局限以及枚举的优缺点及示例详细说明枚举的用处,以及扩展知识枚举的位运算

字面量类型的问题

字面量类型有一些局限性:

1. 缺乏灵活性:字面量类型只能表示特定的值,无法表示范围或模式。

2. 可读性差:当使用多个字面量类型时,代码可能会变得冗长和难以理解。

3. 可维护性差:逻辑含义和真实的值产生了混淆, 如果需要修改或添加新的字面量值,可能需要在多个地方进行修改。这可能会导致代码维护困难。

例如:

letgender='男'|'女'functiongetUserByGender(g: '男'|'女') {}

这时候就会产生重复代码。

可以用type类型别名规避此问题

typeGender='男'|'女'letgender: GenderfunctiongetUserByGender(g: Gender) {}

相比之下,type类型别名在某些情况下可以提供更好的灵活性和可读性。

type类型别名

优点

  • 灵活性type允许我们使用联合、交叉等方式来组合现有的类型,并且可以进行更复杂的类型操作。这使得我们可以更灵活地定义自定义类型。
  • 可读性type可以为类型起一个有意义的别名,使代码更易读和理解。它可以提高代码的可读性和可维护性。

缺点

  • 可维护性:如果使用过度,type可能会导致代码变得复杂和难以维护。当定义了大量复杂的类型别名时,可能需要花费更多的时间来理解和维护代码。

比如上述示例对用户性别进行判断的时候,需要使用真实的值去进行判断。

例如:

typeGender='男'|'女'letgender: GenderfunctiongetUserByGender(g: Gender) {
// 判断用户为男时if (user.gender==='男') {}
}

如果有多处地方用到这些判断,进行性别判断时,依然使用的是真实的值,而不是逻辑含义的值。后期如果需要将“男”“女”,改成“先生”“女士”就需要改很多地方。

如果使用枚举的话,就可以避免这种情况。

enumGender {
male='男',
female='女'}
letgender: GenderfunctiongetUserByGender(g: Gender) {
if(user.gender===g.male) {
console.log('xxx')
  }
}

相比之下,枚举提供了一种更简单和直观的方式来定义一组具有命名值的常量。

枚举

使用枚举我们可以定义一些带名字的常量。 使用枚举可以清晰地表达意图或创建一组有区别的用例。 TypeScript支持数字的和基于字符串的枚举。

如何定义一个枚举:

在TypeScript中,可以使用关键字enum来定义一个枚举。

enum枚举名{
枚举字段1=值1,
枚举字段2=值2,
...}

以下是一个简单的示例:

enumDirection {
Up,
Down,
Left,
Right}

在上面的示例中,我们定义了一个名为Direction的枚举,它包含了四个常量值:UpDownLeftRight。默认情况下,这些常量值会被赋予从0开始递增的数字索引。因此,在这个示例中,Up将被赋值为0,Down将被赋值为1,以此类推。

我们可以使用枚举类型来声明变量,并将其赋值为枚举中的某个常量:

letdirection: Direction=Direction.Up;

我们还可以通过索引访问枚举中的常量:

console.log(Direction.Up); // 输出: 0console.log(Direction[0]); // 输出: "Up"

需要注意的是,在TypeScript中,枚举类型是具有数字和字符串两种形式的。默认情况下,枚举类型是数字形式的。但我们也可以显式地指定每个常量值的数字或字符串:

enumDirection {
Up=1,
Down=2,
Left=3,
Right=4}
enumColor {
Red="RED",
Green="GREEN",
Blue="BLUE"}

在上面的示例中,我们分别定义了一个数字形式的枚举Direction和一个字符串形式的枚举Color。我们可以根据实际需求选择使用哪种形式。

枚举还支持一些特殊操作,例如反向映射和常量计算。反向映射允许我们通过枚举值获取对应的名称,常量计算允许我们在枚举中使用表达式来定义常量值。

枚举会出现在编译结果中,编译结果中表现为对象。

编译前:

enumGender {
male='男',
female='女'}
letgender: Gendergender=Gender.malegender=Gender.female

编译结果:

varGender;
(function (Gender) {
Gender["male"] ="\u7537";
Gender["female"] ="\u5973";
})(Gender|| (Gender= {}));
letgender;
gender=Gender.male;
gender=Gender.female;

优点

  • 1. 可读性: 枚举提供了一种直观的方式来表示一组常量值,并且可以通过名称访问这些常量值。
  • 2. 类型安全: 枚举在编译时会进行类型检查,确保只能使用枚举中定义的常量值。

然而,枚举也有一些局限性:

  • 1. 不能动态扩展:枚举在定义时就确定了所有可能的值,无法在运行时动态添加新的值。
  • 2. 不能进行复杂操作:枚举只能表示一组离散的常量值,无法表示范围或模式。

枚举的位运算

在枚举中,可以使用位运算符来对枚举值进行位运算操作。位运算是一种对二进制数进行操作的方式,它可以对枚举值的各个位进行逻辑运算,从而实现一些特定的功能。

以下是常用的位运算符及其功能:

  1. 按位与(&):将两个操作数的每个对应位进行与运算,结果中每个位都是两个操作数对应位上都为1时才为1,否则为0。
  2. 按位或(|):将两个操作数的每个对应位进行或运算,结果中每个位都是两个操作数对应位上至少有一个为1时才为1,否则为0。
  3. 按位异或(^):将两个操作数的每个对应位进行异或运算,结果中每个位都是两个操作数对应位上不相同时才为1,相同时为0。
  4. 按位取反(~):将操作数的每一位取反。

下面是一个示例说明如何使用枚举和按位运算符来表示和处理权限:

enumPermission {
Read=1, // 0001Write=2, // 0010Execute=4, // 0100Delete=8// 1000}
letuserPermission: Permission=Permission.Read|Permission.Write; // 用户权限:读、写functionhasPermission(permission: Permission, checkPermission: Permission): boolean {
return (permission&checkPermission) ===checkPermission;
}
console.log(hasPermission(userPermission, Permission.Read)); // 输出: trueconsole.log(hasPermission(userPermission, Permission.Execute)); // 输出: false

在上面的示例中,我们定义了一个名为Permission的枚举,它表示不同的权限。每个权限都使用二进制表示,其中每个位代表一种权限。然后我们声明了一个变量 userPermission,并将其赋值为 Permission.Read | Permission.Write,表示用户具有读和写的权限。

接下来,我们定义了一个名为 hasPermission 的函数,它接受两个参数:permission 表示用户的权限,checkPermission 表示要检查的权限。在函数内部,我们使用按位与运算符 & 来检查用户是否具有指定的权限。如果结果等于要检查的权限,则返回 true;否则返回 false

最后,我们通过调用 hasPermission 函数来检查用户是否具有读和执行的权限。根据上面定义的 userPermission 的值,输出结果分别为 truefalse

通过使用枚举和位运算符,我们可以方便地对多个权限进行组合和判断。这种方式可以简化代码,并提供更灵活和可扩展的权限控制机制。


总结一下

TypeScript中的枚举是一种用于定义一组具有命名值的常量的数据类型。它可以提高代码的可读性和可维护性,并支持数字和字符串两种形式。

type类型别名相对于字面量具有更大的灵活性和可读性,但在某些情况下可能会导致代码变得复杂和难以维护。枚举提供了一种更简单和直观的方式来定义一组常量值,但在动态扩展和复杂操作方面有一些限制。因此,在选择使用type还是枚举时,需要根据具体情况进行判断。

另外,枚举的位运算运用得当时会有奇效。

目录
相关文章
|
6天前
|
监控 JavaScript 安全
TypeScript在员工上网行为监控中的类型安全实践
本文演示了如何使用TypeScript在员工上网行为监控系统中实现类型安全。通过定义`Website`类型和`MonitoringData`接口,确保数据准确性和可靠性。示例展示了从监控设备获取数据和提交到网站的函数,强调了类型定义在防止错误、提升代码可维护性方面的作用。
40 7
|
5天前
|
JavaScript 前端开发
TypeScript内置类型一览(Record<string,any>等等)(下)
TypeScript内置类型一览(Record<string,any>等等)
|
5天前
|
JavaScript
TypeScript内置类型一览(Record<string,any>等等)(中)
TypeScript内置类型一览(Record<string,any>等等)
|
5天前
|
JavaScript
TypeScript内置类型一览(Record<string,any>等等)(上)
TypeScript内置类型一览(Record<string,any>等等)
|
6天前
|
JavaScript 安全 前端开发
【TypeScript技术专栏】TypeScript中的类型推断与类型守卫
【4月更文挑战第30天】TypeScript的类型推断与类型守卫是提升代码安全的关键。类型推断自动识别变量类型,减少错误,包括基础、上下文、最佳通用和控制流类型推断。类型守卫则通过`typeof`、`instanceof`及自定义函数在运行时确认变量类型,确保类型安全。两者结合使用,优化开发体验,助力构建健壮应用。
|
6天前
|
JavaScript 前端开发 开发者
【TypeScript技术专栏】TypeScript类型系统与接口详解
【4月更文挑战第30天】TypeScript扩展JavaScript,引入静态类型检查以减少错误。其类型系统包括基本类型、数组等,而接口是定义对象结构的机制。接口描述对象外形,不涉及实现,可用于规定对象属性和方法。通过声明、实现接口,以及利用可选、只读属性,接口继承和合并,TypeScript增强了代码的健壮性和维护性。学习和掌握TypeScript的接口对于大型项目开发至关重要。
|
6天前
|
JavaScript 安全 前端开发
【亮剑】TypeScript 由于其强类型的特性,直接为对象动态添加属性可能会遇到一些问题
【4月更文挑战第30天】本文探讨了在 TypeScript 中安全地为对象动态添加属性的方法。基础方法是使用索引签名,允许接受任何属性名但牺牲了部分类型检查。进阶方法是接口扩展,通过声明合并动态添加属性,保持类型安全但可能导致代码重复。高级方法利用 OOP 模式的类继承,确保类型安全但增加代码复杂性。选择哪种方法取决于应用场景、代码复杂性和类型安全性需求。
|
6天前
|
JavaScript 前端开发
TypeScript基础类型
TypeScript基础类型
|
6天前
|
JavaScript 前端开发
typescript 混合类型
typescript 混合类型
|
6天前
|
JavaScript 前端开发 开发者
类型检查:结合TypeScript和Vue进行开发
【4月更文挑战第24天】TypeScript是JavaScript超集,提供类型注解等特性,提升代码质量和可维护性。Vue.js是一款高效前端框架,两者结合优化开发体验。本文指导如何配置和使用TypeScript与Vue:安装TypeScript和Vue CLI,创建Vue项目时选择TypeScript支持,配置`tsconfig.json`,编写`.tsx`组件,最后运行和构建项目。这种结合有助于错误检查和提升开发效率。