在Typescript中使用string值创build一个枚举
以下代码可用于在Typescript中创build一个枚举:
enum e { hello = 1, world = 2 };
这些值可以通过以下方式访问:
e.hello; e.world;
如何创build一个带有string值的枚举?
enum e { hello = "hello", // error: cannot convert string to e world = "world" // error };
TypeScript 2.4
现在有string枚举,所以你的代码只是工作:
enum E { hello = "hello", world = "world" };
🌹
TypeScript 1.8
由于TypeScript 1.8,您可以使用string文字types来为命名string值(这是部分用于枚举)提供可靠和安全的体验。
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
传统支持
打字稿中的枚举是基于数字的。
你可以使用静态成员的类,但是:
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);
在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]);
更新1
要从string值获得枚举成员的数值,可以使用这个:
var str = "Active"; // this will show message '1' alert(States[str]);
更新2
在最新的TypeScript 2.4中,引入了string枚举,如下所示:
enum ActionType { AddUser = "ADD_USER", DeleteUser = "DELETE_USER", RenameUser = "RENAME_USER", // Aliases RemoveUser = DeleteUser, }
有关Typescript 2.4的更多信息,请阅读MSDN上的博客 。
TypeScript 2.4+
您现在可以直接将string值分配给枚举成员:
enum Season { Winter = "winter", Spring = "spring", Summer = "summer", Fall = "fall" }
有关更多信息,请参阅#15486 。
TypeScript 1.8+
在TypeScript 1.8+中,您可以创build一个string文字types来定义types,并为值列表定义一个同名的对象。 它模仿了一个string枚举的预期行为。
这是一个例子:
type MyStringEnum = "member1" | "member2"; const MyStringEnum = { Member1: "member1" as MyStringEnum, Member2: "member2" as MyStringEnum };
这将像一个string枚举工作:
// 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
确保input对象中的所有string! 如果你没有,那么在上面的第一个例子中,variables不会被隐式input到MyStringEnum
。
在打字稿0.9.0.1中,尽pipe发生了编译错误,编译器仍然可以将ts文件编译成js文件。 代码按照我们的预期工作,Visual Studio 2012可以支持自动代码完成。
更新:
在语法上,typescript不允许我们用string值创build一个枚举,但是我们可以破解这个编译器: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']);
操场
TypeScript 2.1 +
在TypeScript 2.1中引入的查找types允许用于模拟string枚举的另一个模式:
// 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'); // 🙁
TypeScript 2.4 +
在版本2.4中,TypeScript引入了对string枚举的本地支持,所以上面的解决scheme是不需要的。 从TS文件:
enum Colors { Red = "RED", Green = "GREEN", Blue = "BLUE", }
为什么不使用本地方式访问枚举的string。
enum e { WHY, NOT, USE, NATIVE } e[e.WHY] // this returns string 'WHY'
您可以在最新的Typescript中使用string枚举:
enum e { hello = <any>"hello", world = <any>"world" };
资料来源: https : //blog.rsuter.com/how-to-implement-an-enum-with-string-values-in-typescript/
更新 – 2016年
制作一系列我现在使用React的string稍微更健壮的方式就是这样:
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);
这是一个相当干净的解决scheme,允许inheritance,使用TypeScript 2.0。 我没有尝试在早期的版本。
奖励:值可以是任何types!
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: // ... }
一个奇怪的方法是:
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"
这适用于我:
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 " }
我只是声明一个接口,并使用该types的variables访问枚举。 保持接口和枚举同步实际上是很容易的,因为如果枚举中的东西发生变化,typescript就会抱怨,像这样。
错误TS2345:“typeof EAbFlagEnum”types的参数不能分配给“IAbFlagEnum”types的参数。 Property'Move'在types'typeof EAbFlagEnum'中缺失。
这种方法的优点是不需要为了在各种情况下使用枚举(接口)而需要types转换,并且因此支持更多types的情况,例如开关/情况。
// 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;
使用variables,而不是枚举,产生所需的结果。
var strVal: string = AbFlagEnum.Edit; switch (strVal) { case AbFlagEnum.Edit: break; case AbFlagEnum.Move: break; case AbFlagEnum.Clone }
标志是我的另一个必需品,所以我创build了一个NPM模块,增加了这个例子,并包含testing。
打字稿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 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)
有很多答案,但我没有看到任何完整的解决scheme。 接受的答案以及enum { this, one }
是,它将通过许多文件分散您正在使用的string值。 我也不太喜欢这个“更新”,它很复杂,也不会使用types。 我认为迈克尔·布罗姆利的回答是最正确的,但是它的界面有点麻烦,可以用types来做。
我正在使用打字稿2.0。*这是我会做的
export type Greeting = "hello" | "world"; export const Greeting : { hello: Greeting , world: Greeting } = { hello: "hello", world: "world" };
let greet: Greeting = Greeting.hello
使用有用的IDE时,它也具有更好的types/hover信息。 退步是你必须两次写string,但至less只有两个地方。
@ 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 @ next中可用的自定义转换器( https://github.com/Microsoft/TypeScript/pull/13940 ),可以使用string文字types创build带有string值的枚举types的对象。
请查看我的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'
Typescript <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
对于源代码链接,您可以find更多,更简单的方法来完成string文字types
我认为你应该试试这个,在这种情况下,variables的值不会改变,它的工作原理和枚举类似,使用像类一样也是唯一的缺点是你可以改变静态variables的值,这就是我们不想在枚举中。
namespace portal { export namespace storageNames { export const appRegistration = 'appRegistration'; export const accessToken = 'access_token'; } }
我曾经在Typescript 1.5中尝试过,如下所示
module App.Constants { export enum e{ Hello= ("Hello") as any, World= ("World") as any } }
export enum PaymentType { Cash = 1, Credit = 2 } var paymentType = PaymentType[PaymentType.Cash];
我想出了这样的解决scheme:
// Utils.ts export function convertEnumValuesToString(obj) { Object.keys(obj).forEach(function (key) { if (isNaN(+key)) { Object.defineProperty(obj, key, { value: key, enumerable: true }); } }); return obj; } // actions/hello.ts import { convertEnumValuesToString } from '../utils' export enum actionTypes { GREETING, FAREWELL_INIT, FAREWELL_DONE } console.log(actionTypes .GREETING) // 0 convertEnumValuesToString(actionTypes); // override to same key-based string values console.log(actionTypes .GREETING) // "GREETING"
超级简单的解决scheme
enum MySeasons { WINTER, SPRING, SUMMER, FALL } let season = MySeasons[0]; //"WINTER"
//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-hacky但是工作: e[String(e.hello)]
如果你想要的主要是简单的debugging(相当types检查),并不需要为枚举指定特殊的值,这就是我正在做的:
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);
如果你想支持遗留的代码/数据存储,你可以保留数字键。
这样,您可以避免input两次值。
非常非常非常简单的带string的Enum(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)) }
Typescript 0.9.0.1
enum e{ hello = 1, somestr = 'world' }; alert(e[1] + ' ' + e.somestr);
打字游乐场