请看一下这个简单的代码:
const enum MyEnum {
Zero
}
const foo: MyEnum.Zero = 0 // OK as expected (since MyEnum.Zero is zero)
const bar: MyEnum.Zero = 1 // OK, but expected Error! Why?
Run Code Online (Sandbox Code Playgroud)
0在这种情况下,如何执行精确的窄数类型?
UPD:枚举似乎已损坏https://github.com/microsoft/TypeScript/issues/11559
在当前 TypeScript 手册的enum部分中并没有真正提到它,但是所有number值都可以分配给任何数字枚举类型。新的 TypeScript 手册的当前草稿如下:
由于历史限制,一些[可分配性]规则很奇怪。例如,任何数字都可以分配给数字枚举,但这不适用于字符串枚举。只有已知是字符串枚举的一部分的字符串才能分配给它。那是因为数字枚举存在于联合类型和文字类型之前,所以它们的规则最初是宽松的。
似乎 TypeScript 中的数字枚举历来被用来支持位域,使用位掩码和按位操作来组合显式声明的枚举值以获得新的值:
enum Color {
Red = 0xFF0000,
Green = 0x00FF00,
Blue = 0x0000FF
}
const yellow: Color = Color.Red | Color.Green; // 0xFFFF00
const white: Color = Color.Red | Color.Green | Color.Blue; // 0xFFFFFF
const blue: Color = white & ~yellow; // 0x0000FF
Run Code Online (Sandbox Code Playgroud)
并且因为枚举的这种使用存在于现实世界的代码中,所以改变这种行为将是一个突破性的变化。而且该语言的维护者似乎并不特别倾向于尝试.
因此,无论好坏,数字枚举被松散地键入为主要与number.
可以滚动您自己的更严格的类似 enum 的对象,但它涉及手动完成许多使用enum语法时自动发生的事情。这是一种可能的实现(它不会为您提供反向映射):
namespace MyEnum {
export const Zero = 0;
export type Zero = typeof Zero;
export const One = 1;
export type One = typeof One;
export const Two = 2;
export type Two = typeof Two;
}
type MyEnum = typeof MyEnum[keyof typeof MyEnum];
const foo: MyEnum.Zero = 0 // okay
const bar: MyEnum.Zero = 1 // error!
Run Code Online (Sandbox Code Playgroud)
其工作原理如下...当您编写 时enum X { Y = 123, Z = 456 },TypeScript 在运行时引入了一个名为 的值X,具有属性X.Y和X.Z。它还引入了类型命名X,X.Y和X.Z。类型X.YandX.Z只是值X.Y和的类型X.Z。但类型X不是值的类型X。相反,它是属性类型的联合X.Y | X.Z。
我使用namespace、export、const和type以上来达到类似的效果。但这里的区别在于数字枚举的可分配性规则不适用,因此您将获得您期望的严格类型检查。
好的,希望有帮助;祝你好运!
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |