一. 概念
TypeScript中的枚举是一种数据类型,它是一组具有预定义名称的有限值的集合。枚举类型可以使代码更加可读、可维护和易于理解。
类似对象,枚举是将一组无序但极度相关数组集合在一起声明存储。
二. 枚举特性
1. 内部进行了双向赋值
enum Numbers {
a,
b,
c
}
源码
var Numbers;
(function(Numbers) {
Numbers[Numbers['a'] = 0] = 'a';
Numbers[Numbers['b'] = 1] = 'b';
Numbers[Numbers['c'] = 2] = 'c';
})(Numbers || (Numbers = {}))
打印结果
console.log(Numbers[a]) // 0
console.log(Numbers['0']) // 'a'
2. 即可以作为一种类型,也可以作为一种存储方式
1.作为一种类型
enum Colors {
SUCCESS = 'green',
DANGER = 'red',
WARN = 'orange'
}
const buttonClor:Colors = Colors['SUCCESS']
console.log(buttonClor) // 'green'
其中Colors作为一种类型
如果直接赋值的话,类型就会改变
enum Colors {
SUCCESS = 'green',
DANGER = 'red',
WARN = 'orange'
}
const buttonClor:Colors = 'green'
会有如下报错
上述例子,在赋值的同时,同时也把buttonClor的类型限制为string,因为buttonClor的赋值范围是固定的,所以用枚举可以缩小其赋值范围,更加准确
2. 作为一种存储方式
例如上述例子,我们也可以通过Colors[‘SUCCESS’]去获取数据,说明枚举Colors作为一个容器,也存储了数据,并支持访问。同时也避免了大量常量的赋值和使用
三. 实战演练
1. 完整代码
enum typeEnum {
ID,
CONTENT,
COMPLETED
}
interface toDoTypeValue {
id: number,
content: string,
completed: boolean
}
const todoSet:toDoTypeValue = {
id: 1,
content: '',
completed: false
}
type typeValue = number | string |boolean
function setTodo (type:typeEnum, value:typeValue) {
switch(type) {
case typeEnum.ID:
todoSet.id = value as number;
break;
case typeEnum.CONTENT:
todoSet.content = value as string;
break;
case typeEnum.COMPLETED:
todoSet.completed = value as boolean;
break;
}
}
setTodo(typeEnum.ID,1)
setTodo(typeEnum.CONTENT,'hello jack')
setTodo(typeEnum.COMPLETED,true);
console.log(todoSet)
打印结果
{
"id": 1,
"content": "hello jack",
"completed": true
}
2. 使用枚举的好处
使用对象中的typeof
function setTodo (value) {
switch(typeof value) {
case 'number':
todoSet.id = value;
break;
case 'string':
todoSet.content = value;
break;
case 'boolean':
todoSet.completed = value;
break;
}
}
缺点:后续对象可能会添加多个属性,所以一种类型可能对应了多个属性,可维护性差。
type使用常量
function setTodo (type,value) {
switch(type) {
case 'id':
todoSet.id = value;
break;
case 'content':
todoSet.content = value;
break;
case 'completed':
todoSet.completed = value;
break;
}
}
setTodo('id',1)
setTodo('content','hello jack')
setTodo('completed',true);
缺点: 如果有多个属性,需要书写多个属性常量,并且多个属性零散,没有统一维护。代码不够优雅,且可维护性差
四. value为什么使用类型断言?
function setTodo (type:typeEnum, value:typeValue) {
switch(type) {
case typeEnum.ID:
todoSet.id = value as number;
break;
case typeEnum.CONTENT:
todoSet.content = value as string;
break;
case typeEnum.COMPLETED:
todoSet.completed = value as boolean;
break;
}
}
因为todoSet的属性的值的类型都是确定的,但是value的值是typeValue的数据类型是多种类型的其中一种,没有确定类型,所以需要断言确定value的类型
type data = string | number
function test(parmas:data):data {
let resdata = parmas;
return resdata
}
像这种resdata未指定类型,就不需要进行类型断言。
总结:在某些特定的情况下,类型别名可能无法提供足够的精度来满足编译器,使用类型断言来显式地将类型转换为相应的类型可以为此类情况提供解决方案。