首页 > 解决方案 > Typescript 中的枚举类型是什么?

问题描述

给定一个函数,该函数的参数应该是enum. 传入的enum可以有不同数量的属性。如何修复该参数的类型?enum本身不是一个类型。

例如:

function (myEnum: mysteriousType){
  //What is that mysteriousType ?
}


用例是构建一个通用方法来从枚举实例化dat.GUI选项,无论枚举中的字符串/数字类型是什么。

标签: typescripttypescript-typings

解决方案


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

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

如果您只知道它是“某种枚举类型”,我不确定您将要做什么但我想这取决于您自己想办法。myEnum


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

const works: { X: 0, Y: 1, Z: 2, [k: number]: string } = E; // works

语言设计者可能会进一步限制这一点,因为反向映射只会产生在正向映射中看到的特定数字键和字符串值,但由于某种原因,它没有像这样实现:

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

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


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

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

还要注意,上面的类型 ( E extends Enum<E>) 允许一些它可能不应该做的事情:

acceptEnum({ foo: 1 }); // works

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

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

但是这里没有什么可做的。正如我上面提到的,enum目前打字的实现并没有尽可能多地限制数字键,所以在编译时似乎没有办法区分一个具有良好反向映射的枚举和一个没有一个的枚举。


希望有帮助。祝你好运!


推荐阅读