Answers:
现在具有字符串枚举,因此您的代码可以正常工作:
enum E {
hello = "hello",
world = "world"
};
🌹
从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);
toString(): string { return this.value; }
toString
,因为它返回返回一个字符串this.value
,并value
为字符串类型。因此,您不能这样做,var x:number = E.hello.toString();
并且如果这样做,var x = E.hello.toString();
x也被string
get()
方法的缺点return this.value
?这样,它将在访问时返回字符串值,而不仅仅是在转换时返回toString()
。
value
在所有类型上看到成员并将它们视为可比较类型。您可以将value
成员设为私有。这样,编译器将看不到它,也不会尝试应用结构化类型。
在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
要从字符串值获取枚举成员的数字值,可以使用以下方法:
var str = "Active";
// this will show message '1'
alert(States[str]);
更新2
在最新的TypeScript 2.4中,引入了字符串枚举,如下所示:
enum ActionType {
AddUser = "ADD_USER",
DeleteUser = "DELETE_USER",
RenameUser = "RENAME_USER",
// Aliases
RemoveUser = DeleteUser,
}
有关TypeScript 2.4的更多信息,请阅读MSDN上的博客。
States[str]
现在不工作。Type 'string' is not assignable to type 'States'
States[str as any]
在当前(2.x)版本的Typescript中进行操作。
TypeScript 2.4+
现在,您可以直接将字符串值分配给枚举成员:
enum Season {
Winter = "winter",
Spring = "spring",
Summer = "summer",
Fall = "fall"
}
有关更多信息,请参见#15486。
TypeScript 1.8+
在TypeScript 1.8+中,您可以创建一个字符串文字类型来定义该类型,并为值列表创建一个具有相同名称的对象。它模仿字符串枚举的预期行为。
这是一个例子:
type MyStringEnum = "member1" | "member2";
const MyStringEnum = {
Member1: "member1" as MyStringEnum,
Member2: "member2" as MyStringEnum
};
它将像字符串枚举一样工作:
// 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
。
在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']);
case Link.LEARN:
会得到一个Cannot convert 'Link.LEARN' to 'string'
构建错误。投射将不起作用。
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'); // 🙁
在版本2.4中,TypeScript引入了对字符串枚举的本机支持,因此不需要上述解决方案。从TS文档:
enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}
Colors["RED"]
将不起作用。任何解决方法的想法(JSON转换都需要)。
为什么不使用访问枚举字符串的本机方法呢?
enum e {
WHY,
NOT,
USE,
NATIVE
}
e[e.WHY] // this returns string 'WHY'
enum Why { Because = "You Can't", Always = "Do Things That Way." }
;)
您可以在最新的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);
<string>e.hello
触发错误。e.hello
仍被编译器视为数字。<number>e.hello
确实可以。有没有办法解决?我所能想到的就是<string><any>e.hello
。
enum Test { a = <any>"b", b = <any>"c", c = <any>"a" }
Test.a === 'c'
<any>
then <string>
,则要做:someStringValue == someEnumValue.toString()
这是一个相当干净的解决方案,允许使用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: // ...
}
一种怪异的方法是:-
呼叫状态
enum Status
{
PENDING_SCHEDULING,
SCHEDULED,
CANCELLED,
COMPLETED,
IN_PROGRESS,
FAILED,
POSTPONED
}
export = Status
实用程序
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 "
}
我只是声明一个接口,并使用该类型的变量访问枚举。使接口和枚举保持同步实际上很容易,因为TypeScript会抱怨枚举是否有所变化,就像这样。
错误TS2345:无法将类型'typeof EAbFlagEnum'的参数分配给类型'IAbFlagEnum'的参数。类型“ typeof EAbFlagEnum”中缺少属性“ Move”。
该方法的优点是不需要在各种情况下使用枚举(接口)进行类型转换,因此可以支持更多类型的情况,例如开关/案例。
// 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模块,该模块添加到此示例中并包括测试。
export default EAbFlagEnum as IAbFlagEnum;
而不是重新声明变量。我还删除了<any>
枚举中的演员表,它工作正常。
更新:TypeScript 3.4
您可以简单地使用as const
:
const AwesomeType = {
Foo: "foo",
Bar: "bar"
} as const;
TypeScript 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),您可以使用字符串文字类型的字符串值创建类似于对象的枚举。
请查看我的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'
打字稿<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
到源链接,您可以找到更多和更轻松的方法来完成字符串文字类型
有很多答案,但是我看不到任何完整的解决方案。可接受的答案以及的问题enum { this, one }
是,它分散了您正使用的字符串值在许多文件中的分布。我也不很喜欢“更新”,它很复杂并且也没有利用类型。我认为Michael Bromley的答案是最正确的,但是它的界面有点麻烦,可以使用类型来完成。
我正在使用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 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)
我认为您应该尝试使用此方法,在这种情况下,变量的值将不会更改,它的工作原理类似于枚举,像类一样使用也可以工作,唯一的缺点是错误地可以更改静态变量的值,这就是我们不需要枚举。
namespace portal {
export namespace storageNames {
export const appRegistration = 'appRegistration';
export const accessToken = 'access_token';
}
}
export enum PaymentType {
Cash = 1,
Credit = 2
}
var paymentType = PaymentType[PaymentType.Cash];
有点js-hacky,但可以工作: 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(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))
}
我一直在寻找一种在打字稿枚举(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 0.9.0.1
enum e{
hello = 1,
somestr = 'world'
};
alert(e[1] + ' ' + e.somestr);
Cannot convert 'string' to 'e'.
。