使用字符串值创建枚举

Fac*_*alm 241 typescript

以下代码可用于enum在TypeScript中创建:

enum e {
    hello = 1,
    world = 2
};
Run Code Online (Sandbox Code Playgroud)

并且可以通过以下方式访问这些值:

e.hello;
e.world;
Run Code Online (Sandbox Code Playgroud)

如何创建enum带字符串值?

enum e {
    hello = "hello", // error: cannot convert string to e
    world = "world"  // error 
};
Run Code Online (Sandbox Code Playgroud)

bas*_*rat 372

TypeScript 2.4

现在有字符串枚举,所以你的代码正常工作:

enum E {
    hello = "hello",
    world = "world"
};
Run Code Online (Sandbox Code Playgroud)

TypeScript 1.8

从TypeScript 1.8开始,您可以使用字符串文字类型为命名字符串值(部分用于枚举的部分)提供可靠且安全的体验.

type Options = "hello" | "world";
var foo: Options;
foo = "hello"; // Okay 
foo = "asdf"; // Error!
Run Code Online (Sandbox Code Playgroud)

更多:https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types

遗产支持

TypeScript中的枚举是基于数字的.

您可以使用具有静态成员的类:

class E
{
    static hello = "hello";
    static world = "world"; 
}
Run Code Online (Sandbox Code Playgroud)

你也可以说清楚:

var E = {
    hello: "hello",
    world: "world"
}
Run Code Online (Sandbox Code Playgroud)

更新: 根据能够执行var test:E = E.hello;以下操作的要求满足此要求:

class E
{
    // boilerplate 
    constructor(public value:string){    
    }

    toString(){
        return this.value;
    }

    // values 
    static hello = new E("hello");
    static world = new E("world");
}

// Sample usage: 
var first:E = E.hello;
var second:E = E.world;
var third:E = E.hello;

console.log("First value is: "+ first);
console.log(first===third); 
Run Code Online (Sandbox Code Playgroud)

  • @BASarat这是真的,打字稿可以处理这种情况,但是我的意思是每次我们知道它总是有带有返回类型的修饰方法,即使对于ts编译器来说也没有必要,但是对于我们的编码人员来说,当我们看到方法定义时会知道输入它返回。 (2认同)

psu*_*lek 110

在TypeScript的最新版本(1.0RC)中,您可以使用以下枚举:

enum States {
    New,
    Active,
    Disabled
} 

// this will show message '0' which is number representation of enum member
alert(States.Active); 

// this will show message 'Disabled' as string representation of enum member
alert(States[States.Disabled]);
Run Code Online (Sandbox Code Playgroud)

更新1

要从字符串值获取枚举成员的数值,可以使用:

var str = "Active";
// this will show message '1'
alert(States[str]);
Run Code Online (Sandbox Code Playgroud)

更新2

在最新的TypeScript 2.4中,引入了字符串枚举,如下所示:

enum ActionType {
    AddUser = "ADD_USER",
    DeleteUser = "DELETE_USER",
    RenameUser = "RENAME_USER",

    // Aliases
    RemoveUser = DeleteUser,
}
Run Code Online (Sandbox Code Playgroud)

有关TypeScript 2.4的更多信息,请阅读MSDN上的博客.

  • 一般来说,这个解决方案是首选的(因为它是一个真正的枚举)但是你对枚举名称的限制很大(因此是'字符串'). (2认同)
  • 截至今日的最佳解决方案. (2认同)
  • 有什么新鲜的吗?因为`States [str]`现在不起作用.`类型'字符串'不能分配给'States'类型 (2认同)

Dav*_*ret 79

TypeScript 2.4+

您现在可以直接将字符串值分配给枚举成员:

enum Season {
    Winter = "winter",
    Spring = "spring",
    Summer = "summer",
    Fall = "fall"
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅#15486.

TypeScript 1.8+

在TypeScript 1.8+中,您可以创建一个字符串文字类型来定义类型,并为值列表创建一个具有相同名称的对象.它模仿字符串枚举的预期行为.

这是一个例子:

type MyStringEnum = "member1" | "member2";

const MyStringEnum = {
    Member1: "member1" as MyStringEnum,
    Member2: "member2" as MyStringEnum
};
Run Code Online (Sandbox Code Playgroud)

哪个将像字符串枚举一样工作:

// implicit typing example
let myVariable = MyStringEnum.Member1; // ok
myVariable = "member2";                // ok
myVariable = "some other value";       // error, desired

// explict typing example
let myExplicitlyTypedVariable: MyStringEnum;
myExplicitlyTypedVariable = MyStringEnum.Member1; // ok
myExplicitlyTypedVariable = "member2";            // ok
myExplicitlyTypedVariable = "some other value";   // error, desired
Run Code Online (Sandbox Code Playgroud)

确保在对象中键入所有字符串!如果不这样做,那么在上面的第一个例子中,变量不会被隐式输入MyStringEnum.


MIN*_*uma 40

在TypeScript 0.9.0.1中,虽然它发生编译器错误,但编译器仍然可以将ts文件编译为js文件.代码按预期工作,Visual Studio 2012可以支持自动代码完成.

更新:

在语法中,TypeScript不允许我们使用字符串值创建枚举,但我们可以破解编译器:p

enum Link
{
    LEARN   =   <any>'/Tutorial',
    PLAY    =   <any>'/Playground',
    GET_IT  =   <any>'/#Download',
    RUN_IT  =   <any>'/Samples',
    JOIN_IN =   <any>'/#Community'
}

alert('Link.LEARN:    '                     + Link.LEARN);
alert('Link.PLAY:    '                      + Link.PLAY);
alert('Link.GET_IT:    '                    + Link.GET_IT);
alert('Link[\'/Samples\']:    Link.'        + Link['/Samples']);
alert('Link[\'/#Community\']    Link.'      + Link['/#Community']);
Run Code Online (Sandbox Code Playgroud)

操场

  • 好笑,我想知道为什么TypeScript不仅仅支持枚举字符串...很多人都想要这个(包括我). (5认同)

Mic*_*ley 22

TypeScript 2.1 +

TypeScript 2.1中引入的查找类型允许另一种模式来模拟字符串枚举:

// String enums in TypeScript 2.1
const EntityType = {
    Foo: 'Foo' as 'Foo',
    Bar: 'Bar' as 'Bar'
};

function doIt(entity: keyof typeof EntityType) {
    // ...
}

EntityType.Foo          // 'Foo'
doIt(EntityType.Foo);   // 
doIt(EntityType.Bar);   // 
doIt('Foo');            // 
doIt('Bad');            //  
Run Code Online (Sandbox Code Playgroud)

TypeScript 2.4 +

在2.4版本中,TypeScript引入了对字符串枚举的本机支持,因此不需要上述解决方案.来自TS文档:

enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE",
}
Run Code Online (Sandbox Code Playgroud)


小智 19

为什么不使用本地方式访问枚举的字符串.

enum e {
  WHY,
  NOT,
  USE,
  NATIVE
}

e[e.WHY] // this returns string 'WHY'
Run Code Online (Sandbox Code Playgroud)

  • 这不回答这个问题.问题不在于访问枚举字符串.`enum为什么{因为="你不能",总是="做那样的事情." } ;;) (19认同)
  • 这是我正在寻找的答案,谢谢!其他解决方案是巧妙的解决方法,但这很简单:) (2认同)

Ric*_*ard 16

您可以在最新的TypeScript中使用字符串枚举:

enum e
{
    hello = <any>"hello",
    world = <any>"world"
};
Run Code Online (Sandbox Code Playgroud)

资料来源:https://blog.rsuter.com/how-to-implement-an-enum-with-string-values-in-typescript/


更新 - 2016年

制作一组我现在用于React的字符串的一种稍微强大的方法是这样的:

export class Messages
{
    static CouldNotValidateRequest: string = 'There was an error validating the request';
    static PasswordMustNotBeBlank: string = 'Password must not be blank';   
}

import {Messages as msg} from '../core/messages';
console.log(msg.PasswordMustNotBeBlank);
Run Code Online (Sandbox Code Playgroud)


Wes*_*y92 10

这是一个相当干净的解决方案,允许继承,使用TypeScript 2.0.我没有在早期版本上尝试这个.

额外奖励:价值可以是任何类型!

export class Enum<T> {
  public constructor(public readonly value: T) {}
  public toString() {
    return this.value.toString();
  }
}

export class PrimaryColor extends Enum<string> {
  public static readonly Red = new Enum('#FF0000');
  public static readonly Green = new Enum('#00FF00');
  public static readonly Blue = new Enum('#0000FF');
}

export class Color extends PrimaryColor {
  public static readonly White = new Enum('#FFFFFF');
  public static readonly Black = new Enum('#000000');
}

// Usage:

console.log(PrimaryColor.Red);
// Output: Enum { value: '#FF0000' }
console.log(Color.Red); // inherited!
// Output: Enum { value: '#FF0000' }
console.log(Color.Red.value); // we have to call .value to get the value.
// Output: #FF0000
console.log(Color.Red.toString()); // toString() works too.
// Output: #FF0000

class Thing {
  color: Color;
}

let thing: Thing = {
  color: Color.Red,
};

switch (thing.color) {
  case Color.Red: // ...
  case Color.White: // ...
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*ins 7

这对我有用:

class MyClass {
    static MyEnum: { Value1; Value2; Value3; }
    = {
        Value1: "Value1",
        Value2: "Value2",
        Value3: "Value3"
    };
}
Run Code Online (Sandbox Code Playgroud)

要么

module MyModule {
    export var MyEnum: { Value1; Value2; Value3; }
    = {
        Value1: "Value1",
        Value2: "Value2",
        Value3: "Value3"
    };
}
Run Code Online (Sandbox Code Playgroud)

8)

更新:发布后不久,我发现了另一种方式,但忘记发布更新(但是,有人已经在上面提到过):

enum MyEnum {
    value1 = <any>"value1 ", 
    value2 = <any>"value2 ", 
    value3 = <any>"value3 " 
}
Run Code Online (Sandbox Code Playgroud)


nis*_*yal 7

一个hacky方式是: -

CallStatus.ts

enum Status
{
    PENDING_SCHEDULING,
    SCHEDULED,
    CANCELLED,
    COMPLETED,
    IN_PROGRESS,
    FAILED,
    POSTPONED
}

export = Status
Run Code Online (Sandbox Code Playgroud)

Utils.ts

static getEnumString(enum:any, key:any):string
{
    return enum[enum[key]];
}
Run Code Online (Sandbox Code Playgroud)

如何使用

Utils.getEnumString(Status, Status.COMPLETED); // = "COMPLETED"
Run Code Online (Sandbox Code Playgroud)


Nat*_*per 6

有很多答案,但我没有看到任何完整的解决方案。接受的答案以及 的问题enum { this, one }在于,它将您恰好在许多文件中使用的字符串值分散。我也不太喜欢“更新”,它很复杂并且也不利用类型。我认为迈克尔布罗姆利的答案是最正确的,但它的界面有点麻烦,可以用类型来做。

我正在使用 TypeScript 2.0.+ ...这就是我要做的

export type Greeting = "hello" | "world";
export const Greeting : { hello: Greeting , world: Greeting } = {
    hello: "hello",
    world: "world"
};
Run Code Online (Sandbox Code Playgroud)

然后像这样使用:

let greet: Greeting = Greeting.hello
Run Code Online (Sandbox Code Playgroud)

使用有用的 IDE 时,它还具有更好的类型/悬停信息。缺点是您必须将字符串写入两次,但至少只在两个地方。


小智 6

更新:打字稿 3.4

您可以简单地使用as const

const AwesomeType = {
   Foo: "foo",
   Bar: "bar"
} as const;
Run Code Online (Sandbox Code Playgroud)

打字稿 2.1

这也可以通过这种方式完成。希望它可以帮助某人。

const AwesomeType = {
    Foo: "foo" as "foo",
    Bar: "bar" as "bar"
};

type AwesomeType = (typeof AwesomeType)[keyof typeof AwesomeType];

console.log(AwesomeType.Bar); // returns bar
console.log(AwesomeType.Foo); // returns foo

function doSth(awesometype: AwesomeType) {
    console.log(awesometype);
}

doSth("foo") // return foo
doSth("bar") // returns bar
doSth(AwesomeType.Bar) // returns bar
doSth(AwesomeType.Foo) // returns foo
doSth('error') // does not compile
Run Code Online (Sandbox Code Playgroud)