用字符串值创建enum

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

enum e {
hello = 1,
world = 2
};

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

e.hello;
e.world;

我如何创建一个字符串值enum ?

enum e {
hello = "hello", // error: cannot convert string to e
world = "world"  // error
};
335613 次浏览

打字稿2.4

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

enum E {
hello = "hello",
world = "world"
};

🌹

打字稿1.8

从TypeScript 1.8开始,你可以使用字符串文字类型为命名字符串值提供可靠和安全的体验(这也是枚举的部分用途)。

type Options = "hello" | "world";
var foo: Options;
foo = "hello"; // Okay
foo = "asdf"; // Error!

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

遗留的支持

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

你可以使用带有静态成员的类:

class E
{
static hello = "hello";
static world = "world";
}

你也可以选择纯色:

var E = {
hello: "hello",
world: "world"
}

< >强更新: 基于能够做一些类似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);

打印稿0.9.0.1

enum e{
hello = 1,
somestr = 'world'
};


alert(e[1] + ' ' + e.somestr);

TypeScript Playground .

这对我来说很管用:

class MyClass {
static MyEnum: { Value1; Value2; Value3; }
= {
Value1: "Value1",
Value2: "Value2",
Value3: "Value3"
};
}

module MyModule {
export var MyEnum: { Value1; Value2; Value3; }
= {
Value1: "Value1",
Value2: "Value2",
Value3: "Value3"
};
}

8)

更新:在发布这篇文章后不久,我发现了另一种方法,但忘记发布更新(然而,上面已经有人提到过了):

enum MyEnum {
value1 = <any>"value1 ",
value2 = <any>"value2 ",
value3 = <any>"value3 "
}

在TypeScript 0.9.0.1中,尽管会出现编译器错误,但编译器仍然可以将ts文件编译为js文件。代码工作如我们所料,Visual Studio 2012可以支持自动代码补全。

更新:

在语法上,TypeScript不允许我们用字符串值创建enum,但我们可以破解编译器: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']);

<一个href = " http://www.typescriptlang.org/Playground/ src = enum % 20链接% d % 0 0 % 7 b % d % 0 a % 20学习3 d % % 09% 20% 20% 20% 09% 3藤% 3 e # 39; % 2 ftutorial& # 39; % 2 c % d % 0 3 d % % 09年玩% 09% 09% 3藤% 3 e # 39; % 2 fplayground& # 39; % 2 c % d % 0 3 d % % 09 get_it % 09% 09% 3藤% 3 e # 39; % 2 f % 23下载# 39;% 2 c % d % 0 3 d % % 09 run_it % 09% 09% 3藤% 3 e # 39; % 2 fsamples& # 39; % 2 c % d % 0 3 d % % 09 join_in % 09% 09% 3藤% 3 e # 39; % 2 f % 23个社区# 39;% d % 0 a % 7 d % 0 d % 0 a % d % 0 aalert (& # 39; 3 Link.LEARN % % 20% 20% 20% 20 & # 39; % 09% 09% 09% 09% 09% 09% 2 b % 20 Link.LEARN) % 3 b % d % 0 aalert (& # 39; Link.PLAY % % 20% 20% 20% 20 & # 39; % 09% 09% 09% 09% 09% 09% 2 b % 20 link.play) % 3 b % d % 0 aalert (& # 39; 3 Link.GET_IT % % 20% 20% 20% 20 & # 39; % 09% 09% 09% 09% 09% 2 b % 20 Link.GET_IT) % 3 b % d % 0 aalert (% 5 b % & # 39;联系5 c # 39; % 2 fsamples % 5 c # 39; % 3 5 d % % 20% 20% 20% 20链接强生# 39;% 09% - 09% % 5 b 2 b % 20联系# 39;% 2 fsamples& # 39; % 5 d) % 3 b % d % 0 aalert (% 5 b % & # 39;联系5 c # 39; % 2 f % 23个社区% 5 c # 39; % 5 d % 20% 20% 20% 20链接强生# 39;% 09% - 09% % 5 b 2 b % 20联系# 39;% 2 f % 23个社区# 39;% 5 d) % 3 b " rel = " nofollow noreferrer title =“破解编译器& lt; any>“游乐场> < / >

一个俗套的说法是:-

CallStatus.ts

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


export = Status

Utils.ts

static getEnumString(enum:any, key:any):string
{
return enum[enum[key]];
}

如何使用

Utils.getEnumString(Status, Status.COMPLETED); // = "COMPLETED"

在最新版本(1.0RC)的TypeScript中,你可以像这样使用枚举:

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]);

更新1

要从string value中获取enum成员的number值,你可以使用这个:

var str = "Active";
// this will show message '1'
alert(States[str]);

更新2

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

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


// Aliases
RemoveUser = DeleteUser,
}

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

最近在使用TypeScript 1.0.1时遇到了这个问题,并以这种方式解决了:

enum IEvents {
/** A click on a product or product link for one or more products. */
CLICK,
/** A view of product details. */
DETAIL,
/** Adding one or more products to a shopping cart. */
ADD,
/** Remove one or more products from a shopping cart. */
REMOVE,
/** Initiating the checkout process for one or more products. */
CHECKOUT,
/** Sending the option value for a given checkout step. */
CHECKOUT_OPTION,
/** The sale of one or more products. */
PURCHASE,
/** The refund of one or more products. */
REFUND,
/** A click on an internal promotion. */
PROMO_CLICK
}


var Events = [
'click',
'detail',
'add',
'remove',
'checkout',
'checkout_option',
'purchase',
'refund',
'promo_click'
];


function stuff(event: IEvents):boolean {
// event can now be only IEvents constants
Events[event]; // event is actually a number that matches the index of the array
}
// stuff('click') won't work, it needs to be called using stuff(IEvents.CLICK)

为什么不直接使用本地方式访问枚举的字符串呢?

enum e {
WHY,
NOT,
USE,
NATIVE
}


e[e.WHY] // this returns string 'WHY'

我认为你应该试试这个,在这种情况下,变量的值不会改变,它的工作方式很像枚举,使用类也可以,唯一的缺点是你可以错误地改变静态变量的值这是我们不希望在枚举中发生的。

namespace portal {


export namespace storageNames {


export const appRegistration = 'appRegistration';
export const accessToken = 'access_token';


}
}

我只是声明了一个接口,并使用该类型的变量访问枚举。保持接口和枚举同步实际上很容易,因为如果枚举中有什么变化,TypeScript会报错,就像这样。

TS2345:类型为“typeof EAbFlagEnum”的参数不可赋值 参数类型为“IAbFlagEnum”。属性“Move”类型缺失 typeof EAbFlagEnum。< / p >

这种方法的优点是在各种情况下使用enum(接口)不需要类型强制转换,因此支持更多类型的情况,例如switch/case。

// Declare a TypeScript enum using unique string
//  (per hack mentioned by zjc0816)


enum EAbFlagEnum {
None      = <any> "none",
Select    = <any> "sel",
Move      = <any> "mov",
Edit      = <any> "edit",
Sort      = <any> "sort",
Clone     = <any> "clone"
}


// Create an interface that shadows the enum
//   and asserts that members are a type of any


interface IAbFlagEnum {
None:   any;
Select: any;
Move:   any;
Edit:   any;
Sort:   any;
Clone:  any;
}


// Export a variable of type interface that points to the enum


export var AbFlagEnum: IAbFlagEnum = EAbFlagEnum;

使用变量,而不是枚举,可以产生所需的结果。

var strVal: string = AbFlagEnum.Edit;


switch (strVal) {
case AbFlagEnum.Edit:
break;
case AbFlagEnum.Move:
break;
case AbFlagEnum.Clone
}

标记是我的另一个需要,所以我创建了一个NPM模块,添加到这个例子中,并包括测试。

https://github.com/djabraham/ts-enum-tools

我在TypeScript 1.5中尝试过,如下所示,它对我来说很有效

module App.Constants {
export enum e{
Hello= ("Hello") as any,
World= ("World") as any
}
}

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

enum e
{
hello = <any>"hello",
world = <any>"world"
};

来源: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);

打印稿2.4 +

你现在可以直接将字符串值分配给enum成员:

enum Season {
Winter = "winter",
Spring = "spring",
Summer = "summer",
Fall = "fall"
}

更多信息请参见# 15486

打印稿1.8 +

在TypeScript 1.8+中,你可以创建一个字符串文字类型来定义类型,并为值列表创建一个同名的对象。它模仿字符串enum的预期行为。

这里有一个例子:

type MyStringEnum = "member1" | "member2";


const MyStringEnum = {
Member1: "member1" as MyStringEnum,
Member2: "member2" as MyStringEnum
};

它将像字符串enum一样工作:

// 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

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

export enum PaymentType {
Cash = 1,
Credit = 2
}
var paymentType = PaymentType[PaymentType.Cash];

这里有一个相当干净的解决方案,它允许继承,使用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: // ...
}

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('Bar');            // 👍
doIt('Baz');            // 🙁

TypeScript 2.4 +

在2.4版中,TypeScript引入了对字符串enum的本地支持,所以上面的解决方案是不需要的。TS文档中写道:

enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}

有很多答案,但我没有看到任何完整的解决方案。接受的答案以及enum { this, one }的问题是,它分散了你碰巧在许多文件中使用的字符串值。我不太喜欢“更新”;或者,它很复杂,也没有利用类型。我认为迈克尔·布罗姆利的回答是最正确的,但它的接口有点麻烦,可以用一个类型。

我使用的是TypeScript 2.0。+……这是我会做的

export type Greeting = "hello" | "world";
export const Greeting : { hello: Greeting , world: Greeting } = {
hello: "hello",
world: "world"
};

然后像这样使用:

let greet: Greeting = Greeting.hello

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

@basarat的回答很棒。下面是一个你可以使用的简化但有点扩展的例子:

export type TMyEnumType = 'value1'|'value2';


export class MyEnumType {
static VALUE1: TMyEnumType = 'value1';
static VALUE2: TMyEnumType = 'value2';
}


console.log(MyEnumType.VALUE1); // 'value1'


const variable = MyEnumType.VALUE2; // it has the string value 'value2'


switch (variable) {
case MyEnumType.VALUE1:
// code...


case MyEnumType.VALUE2:
// code...
}

更新:TypeScript 3.4

你可以简单地使用as const:

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

打字稿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

使用typescript@next中提供的自定义转换器(https://github.com/Microsoft/TypeScript/pull/13940),您可以从字符串文本类型中创建string值,例如object。

请查看我的npm包ts-transformer-enumerate

使用示例:

// The signature of `enumerate` here is `function enumerate<T extends string>(): { [K in T]: K };`
import { enumerate } from 'ts-transformer-enumerate';


type Colors = 'green' | 'yellow' | 'red';
const Colors = enumerate<Colors>();


console.log(Colors.green); // 'green'
console.log(Colors.yellow); // 'yellow'
console.log(Colors.red); // 'red'
//to access the enum with its string value you can convert it to object
//then you can convert enum to object with proberty
//for Example :


enum days { "one" =3, "tow", "Three" }


let _days: any = days;


if (_days.one == days.one)
{
alert(_days.one + ' | ' + _days[4]);
}

有点js-hack,但有效:e[String(e.hello)]

如果你想要的主要是易于调试(相当类型检查),不需要为枚举指定特殊值,这是我正在做的:

export type Enum = { [index: number]: string } & { [key: string]: number } | Object;


/**
* inplace update
* */
export function enum_only_string<E extends Enum>(e: E) {
Object.keys(e)
.filter(i => Number.isFinite(+i))
.forEach(i => {
const s = e[i];
e[s] = s;
delete e[i];
});
}


enum AuthType {
phone, email, sms, password
}
enum_only_string(AuthType);

如果您希望支持遗留代码/数据存储,则可以保留数字键。

这样,您就可以避免键入两次值。

非常非常简单的Enum string (TypeScript 2.4)

import * from '../mylib'


export enum MESSAGES {
ERROR_CHART_UNKNOWN,
ERROR_2
}


export class Messages {
public static get(id : MESSAGES){
let message = ""
switch (id) {
case MESSAGES.ERROR_CHART_UNKNOWN :
message = "The chart does not exist."
break;
case MESSAGES.ERROR_2 :
message = "example."
break;
}
return message
}
}


function log(messageName:MESSAGES){
console.log(Messages.get(messageName))
}

打印稿& lt;2.4

/** Utility function to create a K:V from a list of strings */
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
return o.reduce((res, key) => {
res[key] = key;
return res;
}, Object.create(null));
}


/**
* Sample create a string enum
*/


/** Create a K:V */
const Direction = strEnum([
'North',
'South',
'East',
'West'
])
/** Create a Type */
type Direction = keyof typeof Direction;


/**
* Sample using a string enum
*/
let sample: Direction;


sample = Direction.North; // Okay
sample = 'North'; // Okay
sample = 'AnythingElse'; // ERROR!

https://basarat.gitbooks.io/typescript/docs/types/literal-types.html

到源代码链接,你可以找到更多更简单的方法来实现字符串文字类型

我正在寻找一种方法来实现typescript枚举中的描述(v2.5),这种模式适合我:

export enum PriceTypes {
Undefined = 0,
UndefinedDescription = 'Undefined' as any,
UserEntered = 1,
UserEnteredDescription = 'User Entered' as any,
GeneratedFromTrade = 2,
GeneratedFromTradeDescription = 'Generated From Trade' as any,
GeneratedFromFreeze = 3,
GeneratedFromFreezeDescription = 'Generated Rom Freeze' as any
}

...

    GetDescription(e: any, id: number): string {
return e[e[id].toString() + "Description"];
}
getPriceTypeDescription(price: IPricePoint): string {
return this.GetDescription(PriceTypes, price.priceType);
}

我也有同样的问题,然后想出了一个很好用的函数:

  • 每个条目的键和值都是字符串,并且相同。
  • 每个条目的值都是从键派生出来的。(即。“不要重复自己”,不像字符串值的常规枚举)
  • TypeScript类型成熟且正确。(防止拼写错误)
  • 还有一种简单的方法可以让TS自动完成您的选项。(如。输入MyEnum.,并立即看到可用的选项)
  • 还有其他一些优点。(见答案底部)

效用函数:

export function createStringEnum<T extends {[key: string]: 1}>(keysObj: T) {
const optionsObj = {} as {
[K in keyof T]: keyof T
// alternative; gives narrower type for MyEnum.XXX
//[K in keyof T]: K
};
const keys = Object.keys(keysObj) as Array<keyof T>;
const values = keys; // could also check for string value-overrides on keysObj
for (const key of keys) {
optionsObj[key] = key;
}
return [optionsObj, values] as const;
}

用法:

// if the "Fruit_values" var isn't useful to you, just omit it
export const [Fruit, Fruit_values] = createStringEnum({
apple: 1,
pear: 1,
});
export type Fruit = keyof typeof Fruit; // "apple" | "pear"
//export type Fruit = typeof Fruit_values[number]; // alternative


// correct usage (with correct types)
let fruit1 = Fruit.apple; // fruit1 == "apple"
fruit1 = Fruit.pear; // assigning a new fruit also works
let fruit2 = Fruit_values[0]; // fruit2 == "apple"


// incorrect usage (should error)
let fruit3 = Fruit.tire; // errors
let fruit4: Fruit = "mirror"; // errors

现在有人可能会问,这种“基于字符串的枚举”的优点是什么?超过刚刚使用:

type Fruit = "apple" | "pear";

有几个优点:

  1. 自动完成功能更好一些。例如,如果你输入let fruit = Fruit., Typescript会立即列出可用选项的确切集合。对于字符串字面量,您需要显式地定义您的类型,例如。let fruit: Fruit = ,然后按ctrl+空格之后。(甚至会导致不相关的自动完成选项显示在有效选项下面)
  2. 选项的TSDoc元数据/描述被转移到MyEnum.XXX字段!这对于提供关于不同选项的附加信息非常有用。例如: < img src = " https://i.imgur.com/Wn1MFsY.png " alt = " / > < /李>
  3. 您可以在运行时访问选项列表(例如。Fruit_values,或手动使用Object.values(Fruit))。使用type Fruit = ...方法,没有内置的方法来做到这一点,这切断了许多用例。(例如,我使用运行时值来构造json模式)

Typescript中的字符串枚举:

字符串枚举是一个类似的概念,但是有一些细微的运行时差异,如下文所述。在string enum中,每个成员必须用string字面值或另一个string enum成员常量初始化。

enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
虽然字符串枚举没有自动递增的行为,但字符串枚举的好处是它们很好地“序列化”。换句话说,如果你正在调试并且必须读取一个数值enum的运行时值,这个值通常是不透明的——它本身没有传达任何有用的含义(尽管反向映射通常会有所帮助),字符串enum允许你在代码运行时给出一个有意义且可读的值,与枚举成员本身的名称无关。

.参考链接如下

enter link description here