Typescript 中的枚举类型是什么? [英] What is the type of an enum in Typescript?

查看:28
本文介绍了Typescript 中的枚举类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Given a function that has an argument supposed to be an enum. The enum passed in can have different numbers of properties. How to fix the type of that argument ? enum itself is not a type.

例如:

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

<小时>用例是构建一个通用方法来实例化 dat.GUI 枚举中的选项,无论枚举中的字符串/数字类型如何.


The use case is to build a generic method to instantiate dat.GUI options from an enum, whatever the string/number type in the enum.

推荐答案

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

With what you've stated so far (needs to accept all string / numeric / heterogeneous enums), the closest I can do is something like this:

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 做什么,但我想这取决于你来弄清楚.

I'm not sure what you're going to do with myEnum if all you know is that it's "some enum type", but I guess that's up to you to figure out.

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

How I came up with this: I examined a bunch of concrete enum types, and they seem to have properties with string keys and string or numeric values (the forward mapping), as well as a numeric index key with string values (the reverse mapping for numeric values).

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

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

The language designers might have constrained this further, since the reverse mapping will only produce the specific numeric keys and string values seen in the forward mapping, but for some reason it's not implemented like that:

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.

So the tightest constraint I can put on an enum type is the above E extends Enum<E>.

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

Note that this code does not work for const enum types which don't really exist at runtime:

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

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

And also note that the above type (E extends Enum<E>) allows some things it maybe shouldn't:

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

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

In the above, {foo: 1} is plausibly a numeric enum similar to enum Foo {foo = 1} but it doesn't have the reverse mapping, and if you rely on that things will blow up at runtime. Note that {foo: 1} doesn't seem to have an index signature but it still matches an index signature implicitly. It wouldn't fail to match unless you added some explicit bad value:

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

但是这里没有什么可做的.正如我上面提到的,enum 类型的实现目前并没有尽可能多地限制数字键,因此在编译时似乎无法区分具有良好反向映射的枚举一无二.

But there's nothing to be done here. As I mentioned above, the implementation of enum typing currently does not constrain the numeric keys as much as it can, so there seems to be no way at compile time to distinguish between an enum with a good reverse mapping and one without one.

希望有所帮助.祝你好运!

Hope that helps. Good luck!

这篇关于Typescript 中的枚举类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆