简体   繁体   English

从联合类型创建TypeScript(字符串)枚举?

[英]Create a TypeScript (string) enum from a union type?

If I have a TypeScript union like so: 如果我有这样的TypeScript联合:

type SomeUnion = 'Foo' | 'Bar' | 'Baz';

Is there a way I can convert this into a string-based enum? 有没有一种方法可以将其转换为基于字符串的枚举? Like the the following: 如下所示:

enum SomeUnionBasedEnum {
  Foo = 'Foo',
  Bar = 'Bar',
  Baz = 'Baz'
}

I am trying to model an enum that represents the permissions in our system, but those permissions are in some cases automatically generated union types. 我正在尝试对代表我们系统中权限的枚举建模,但是在某些情况下,这些权限是自动生成的联合类型。 I want a way to combine them into a single enum because enums provide a better developer experience by limiting the intellisense to the permissible values. 我想要一种将它们组合成单个枚举的方法,因为枚举通过将智能感知限制为允许的值来提供更好的开发人员体验。 For example AppPermisionEnum.<available enum values> . 例如AppPermisionEnum.<available enum values> I'd also be open to ways to combine enums into a single enum, but I don't think that's possible. 我也乐于将枚举合并为单个枚举,但是我认为这是不可能的。 My end goal is to have an enum comprised of values from a couple different sources. 我的最终目标是让一个枚举包含几个不同来源的值。

Like I pointed out in the comments string literal types already offer good intelisense support, so I personally would just use those and not bother creating anything else, the developer experience is already great. 就像我在注释字符串中指出的那样,文字类型已经提供了良好的智力支持,因此我个人将只使用它们而不必费心创建任何其他内容,因此开发人员的经验已经很棒。

The code below is a solution in search of a problem but we can do something close to what you want. 下面的代码是解决问题的解决方案,但是我们可以做一些您想要的事情。

You can't create an enum, but you can create an object that has all the properties of the union and each property has the same value as the key, using a mapped type. 您无法创建枚举,但是可以使用映射类型创建具有并集的所有属性且每个属性与键具有相同值的对象。 You will need to maintain these objects manually, but typescript will issue a warning if ever they are out of sync so maintaining them should not be an issue. 您将需要手动维护这些对象,但是打字稿将在它们不同步时发出警告,因此维护它们应该不是问题。

type SomeUnion = 'Foo' | 'Bar' | 'Baz';

function createEnumObject<T extends string>(o: { [P in T]: P }) {
    return o;
}

const SomeUnion = createEnumObject<SomeUnion>({
    Foo: "Foo",
    Bar: "Bar",
    Baz: "Baz"
})

let o: SomeUnion = SomeUnion.Bar;

Converting a union (ie a type) to an object (ie a value) without extra code is in principle not possible, types are erased at compile time so can't be relied upon for anything at run-time and typescript has a strict policy against type directed emit. 原则上不可能在没有额外代码的情况下将联合(即类型)转换为对象(即值),在编译时会擦除类型,因此在运行时不能依赖任何内容,并且打字稿具有严格的政策针对类型定向发射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM