Typescript中的枚举类型是什么?

Atr*_*sis 7 typescript typescript-typings

给定一个函数,其参数应为enum。该enum传入可以有属性的不同的数字。如何确定该参数的类型?enum本身不是一种类型。

例如:

function (myEnum: mysteriousType){
  //What is that mysteriousType ?
}
Run Code Online (Sandbox Code Playgroud)


用例是构建一个通用方法来从枚举实例化dat.GUI选项,而不管枚举中的字符串/数字类型如何。

jca*_*alz 10

到目前为止,您所说的内容(需要接受所有字符串/数字/异构枚举),我能做的最接近的事情是这样的:

type Enum<E> = Record<keyof E, number | string> & { [k: number]: string };
function acceptEnum<E extends Enum<E>>(
  myEnum: E
): void { 
  // do something with myEnum... what's your use case anyway?
}

enum E { X, Y, Z };
acceptEnum(E); // works
Run Code Online (Sandbox Code Playgroud)

我不知道你会怎么myEnum,如果你知道的是,它的“某些枚举类型”,但我想这是由你来弄清楚。


我是怎么enum想到的:我检查了一堆具体类型,它们似乎具有带字符串键和字符串或数字值的属性(正向映射),以及带字符串值的数字索引键(用于反向映射的属性)。数值)。

const works: { X: 0, Y: 1, Z: 2, [k: number]: string } = E; // works
Run Code Online (Sandbox Code Playgroud)

语言设计人员可能已经进一步限制了此操作,因为反向映射将只生成在向前映射中看到的特定数字键和字符串值,但由于某些原因,它没有这样实现:

const doesntWork: { X: 0, Y: 1, Z: 2, [k: number]: 'X' | 'Y' | 'Z' } = E; // error
const alsoDoesntWork: { X: 0, Y: 1, Z: 2, 0: 'X', 1: 'Y', 2: 'Z' } = E; // error
Run Code Online (Sandbox Code Playgroud)

所以我可以对枚举类型施加的最严格的约束是上述E extends Enum<E>


请注意,此代码不适用于const enum运行时实际上不存在的类型:

const enum F {U, V, W};
acceptEnum(F); // nope, can't refer to `F` by itself
Run Code Online (Sandbox Code Playgroud)

另外请注意,上述类型(E extends Enum<E>)允许执行某些可能不应该做的事情:

acceptEnum({ foo: 1 }); // works
Run Code Online (Sandbox Code Playgroud)

在上面,{foo: 1}似乎是一个类似于数字枚举的枚举,enum Foo {foo = 1}但是它没有反向映射,如果您依靠它,那么事情将在运行时崩溃。请注意,{foo: 1}似乎没有索引签名,但它仍隐式匹配索引签名。除非添加了一些明确的错误值,否则它不会失败:

acceptEnum({foo: 1, 2: 3}); // error, prop '2' not compatible with index signature
Run Code Online (Sandbox Code Playgroud)

但是这里没有什么可做的。正如我上面提到的,enum键入的实现当前并没有最大程度地限制数字键,因此在编译时似乎无法区分具有良好反向映射的枚举和没有反向映射的枚举。


希望能有所帮助。祝好运!