Tìm kiếm trang web

typescript - Tạo một enum với các giá trị chuỗi


Đoạn mã sau có thể được sử dụng để tạo một enum trong TypeScript:

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

Và các giá trị có thể được truy cập bằng:

e.hello;
e.world;

Làm thế nào để tôi tạo một enum với các giá trị chuỗi?

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

Câu trả lời #1

TypeScript 2.4

Bây giờ có các enum chuỗi nên mã của bạn chỉ cần hoạt động:

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

🌹

TypeScript 1.8

Kể từ TypeScript 1.8, bạn có thể sử dụng các kiểu hằng chuỗi để cung cấp một trải nghiệm đáng tin cậy và an toàn cho các giá trị chuỗi được đặt tên (một phần mục đích mà enum được sử dụng).

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

Thêm: https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types

Hỗ trợ di sản

Các enum trong TypeScript dựa trên số.

Bạn có thể sử dụng một lớp với các thành viên tĩnh mặc dù:

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

Bạn cũng có thể chọn kiểu đơn giản:

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

Cập nhật: Dựa trên yêu cầu có thể làm điều gì đó như var test:E=E.hello; thì điều sau đây thỏa mãn điều này:

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

Câu trả lời #2

Trong phiên bản mới nhất (1.0RC) của TypeScript, bạn có thể sử dụng enum như sau:

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

Cập nhật 1

Để lấy giá trị số của thành viên enum từ giá trị chuỗi, bạn có thể sử dụng điều này:

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

Cập nhật 2

Trong TypeScript 2.4 mới nhất, đã giới thiệu các enum kiểu chuỗi, như sau:

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

    // Aliases
    RemoveUser = DeleteUser,
}

Để biết thêm thông tin về TypeScript 2.4, hãy đọc blog trên MSDN.

Câu trả lời #3

TypeScript 2.4+

Bây giờ bạn có thể gán giá trị chuỗi trực tiếp cho các thành viên enum:

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

Xem #15486 để biết thêm thông tin.

TypeScript 1.8+

Trong TypeScript 1.8+, bạn có thể tạo một kiểu literal chuỗi để định nghĩa kiểu và một đối tượng cùng tên cho danh sách các giá trị. Nó mô phỏng hành vi mong đợi của một enum chuỗi.

Đây là một ví dụ:

type MyStringEnum = "member1" | "member2";

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

Cái này sẽ hoạt động giống như một enum chuỗi:

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

Hãy chắc chắn gõ tất cả các chuỗi trong đối tượng! Nếu bạn không làm như vậy thì trong ví dụ đầu tiên ở trên, biến sẽ không được kiểu ngầm định thành MyStringEnum.

Câu trả lời số 4

Trong TypeScript 0.9.0.1, mặc dù xảy ra lỗi biên dịch, trình biên dịch vẫn có thể biên dịch tệp ts thành tệp js. Mã hoạt động như chúng ta mong đợi và Visual Studio 2012 có thể hỗ trợ hoàn thành mã tự động.

Cập nhật :

Trong cú pháp, TypeScript không cho phép chúng ta tạo một enum với các giá trị chuỗi, nhưng chúng ta có thể hack compiler :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']);

Sân chơi

Câu trả lời số 5

TypeScript 2.1 +

Các kiểu tra cứu, được giới thiệu trong TypeScript 2.1, cho phép một mẫu khác để mô phỏng các enum chuỗi:

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

Với phiên bản 2.4, TypeScript đã giới thiệu hỗ trợ gốc cho các enum chuỗi, vì vậy giải pháp ở trên là không cần thiết. Theo tài liệu TS:

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

Câu trả lời số 6

Tại sao không chỉ sử dụng cách gốc để truy cập các chuỗi của một enum.

enum e {
  WHY,
  NOT,
  USE,
  NATIVE
}

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

Câu trả lời #7

Bạn có thể sử dụng enum chuỗi trong TypeScript mới nhất:

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

Nguồn: https://blog.rsuter.com/how-to-implement-an-enum-with-string-values-in-typescript/

CẬP NHẬT - 2016

Một cách hơi chắc chắn hơn để tạo một tập hợp các chuỗi mà tôi sử dụng cho React hiện nay là như sau:

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

Câu trả lời #8

CẬP NHẬT: TypeScript 3.4

Bạn có thể đơn giản sử dụng as const:

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

TypeScript 2.1

Điều này cũng có thể được thực hiện theo cách này. Hy vọng nó giúp được ai đó.

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

Câu trả lời #9

Đây là một giải pháp khá gọn gàng cho phép kế thừa, sử dụng TypeScript 2.0. Tôi chưa thử điều này trên phiên bản cũ hơn.

Thưởng: giá trị có thể là bất kỳ loại nào!

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: // ...
}

Bài viết liên quan