enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square, // TS2322: Type 'ShapeKind.Square' is not assignable to type 'ShapeKind.Circle'. The expected type comes from property 'kind' which is declared here on type 'Circle'
radius: 100
}
运行时的枚举类型
枚举类型是真正的对象,存在于运行时。比如下面的枚举:
enum E {
X, Y, Z
}
它可以被传递给下面的函数:
enum E {
X, Y, Z
}
function f(obj: { X: number }) {
return obj.X
}
console.log(f(E)) // 0
原文地址:http://www.typescriptlang.org/docs/handbook/enums.html 不错的学习枚举类型的文章: https://www.cnblogs.com/wjaaron/p/11672764.html https://www.cnblogs.com/xjy20170907/p/10882885.html
数字枚举(Numeric enums)
1、定义一个 enum
输出如下:
2、使用
3、下面的定义会报错
字符串枚举(String enums)
举例
1、字符串枚举没有自动增加的功能(数字枚举有这个功能);
异类枚举(Heterogeneous enums)
技术上,可以在枚举类型中混合使用数字和字符串,但是不推荐使用。
枚举类型的计算成员 和 常量成员
每一个枚举类型的成员可能有两种值,一个是计算值,一个是常量。
成员为 常量 的情形:
1、枚举类型中的第一个成员,并且没有被初始化。这种情况下它会被赋值 0 :
2、这个成员本身没有被初始化,并且它前面的成员是一个数字常量。这种情况下,当前成员的值是在前一个成员的值的基础上加 1 。
3、成员被一个 常量枚举表达式(constant enum expression)初始化。 常量枚举表达式 是TypeScript表达式的子集,能在编译时被完全编译。
一个表达式如果满足下面的一个条件,它就是一个 常量枚举表达式:
1、一个字面量枚举表达式(基本上就是一个字符串字面量 或者是 一个数字字面量); 2、对以前定义的 常量枚举成员的引用(可以来自不同的枚举); 3、带小括号的常量枚举表达式; 4、应用于常量枚举表达式的“+”、“-”、“~”一元运算符之一; 5、以常量枚举表达式作为操作数的这些二元运算符:+, -, *, /, %, <<, >>, >>>, &, |, ^ 。
如果常量枚举表达式计算为 NaN 或者 Infinity,编译时将报错。
所有其他的情况枚举成员都被认为是 计算成员
联合枚举 及 枚举成员类型
有一个常量枚举成员的特别的子集,它们没有被计算进去:字面量枚举成员。一个字面量枚举成员 是一个常量枚举成员,它没有被初始化,或者值被下面的值初始化:
当一个枚举类型中的所有成员都是字面量枚举值,可以对其执行一些特殊的语法。
首先,枚举成员可以当做 类型 使用
我们可以指定一个成员它的类型是 一个枚举成员:
运行时的枚举类型
枚举类型是真正的对象,存在于运行时。比如下面的枚举:
它可以被传递给下面的函数:
编译时的枚举类型
尽管枚举类型是真实的对象,存在于运行时,但是如果对它执行 keyof 操作,它的表现会和你的预期不一样,不同于在普通的对象上执行 keyof 操作。
所以我们一般使用
keyof typeof
运算符来获得一个枚举类型的所有键,以字符串的形式返回。反向映射
除了用属性名作为一个成员添加了一个对象,数字枚举成员同样获得了一个从枚举值到枚举名称的反向映射。比如下面的例子:
TypeScript会将上面的代码编译为:
如果将枚举的成员的值设置为了字符串,那么这个成员是没有反向映射的。
常量枚举(const enums)
在大多数情况下,enum 是一个完美有效的解决方案,但有时要求会更加苛刻。为了避免花掉额外的开销去生成代码,或者额外地迂回不直接地才能访问到一个枚举类型的值,我们可以使用 常量枚举(const enums)。const enum就是在定义枚举时在前面加上 const:
1、上面的代码是原文中的例子,但是我在编辑器中输入上面的代码,TypeScript报错:“'const' enums are not supported ”,如下:
typescript@3.7.5 是不是不支持 const enums 了这个问题还要再了解,现在暂不清楚。
下面来举个例子先说明 const enums 到底是什么意思。
看下面的代码:
上面的代码经过TypeScript 的编译,编译为了下面的JavaScript:
可以看到: 1、普通枚举类型 Status 被编译为了一个对象,它有 Off 属性,值为 0;有 0 属性,值为 "Off";有 On 属性,值为 1 ;还有 1 属性,值为 “On”; 2、而 常量枚举类型 Animal 根本没有出现在 编译后的代码中, 只出现了它的一个属性的值(Animal的Dog属性的值 0 替换了 Animal.Dog)。所以在TypeScript 编译过程中,会用到 const enum,但是编译完成后,就会完全移除它。 3、这样做可能是为了减少编译后的代码量,而之所以出现 const enum,只是为了在编写 .ts 时更加直观方便。
外部枚举(Ambient Enums)
外部枚举是使用 declare enum 定义的枚举类型:
declare定义的类型只会用于编译时的检查,编译结果中会被删除。 上面的代码会被编译为:
外部枚举与声明语句一样,常出现在声明文件中。
同时使用 declare 和 const 也是可以的。
上面的代码会被编译为:
如果只写const enum:
它会被编译为:
跟上面写 declare const 编译的结果是一样的,所以 declare const 和 const 有什么区别呢?