Tôi muốn lặp lại một TypeScript enum
và nhận từng tên biểu tượng liệt kê, ví dụ:
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Tôi muốn lặp lại một TypeScript enum
và nhận từng tên biểu tượng liệt kê, ví dụ:
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Câu trả lời:
Mã bạn đã đăng sẽ hoạt động; nó sẽ in ra tất cả các thành viên của enum, bao gồm các giá trị của các thành viên enum. Ví dụ: đoạn mã sau:
enum myEnum { bar, foo }
for (var enumMember in myEnum) {
console.log("enum member: ", enumMember);
}
Sẽ in như sau:
Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo
Thay vào đó, nếu bạn chỉ muốn tên thành viên chứ không phải các giá trị, bạn có thể làm một cái gì đó như thế này:
for (var enumMember in myEnum) {
var isValueProperty = parseInt(enumMember, 10) >= 0
if (isValueProperty) {
console.log("enum member: ", myEnum[enumMember]);
}
}
Điều đó sẽ in ra chỉ tên:
Thành viên Enum: thanh
Thành viên Enum: foo
Hãy cẩn thận: điều này hơi phụ thuộc vào một chi tiết triển khai: TypeScript biên dịch enum thành một đối tượng JS với các giá trị enum là thành viên của đối tượng. Nếu TS quyết định thực hiện chúng khác nhau trong tương lai, kỹ thuật trên có thể bị phá vỡ.
+enumMember >= 0
này là isFinite(+enumMember)
do các giá trị âm hoặc dấu phẩy động cũng được ánh xạ ngược lại. ( Sân chơi )
Mặc dù câu trả lời đã được cung cấp, nhưng hầu như không ai chỉ vào tài liệu
Đây là một đoạn
enum Enum {
A
}
let nameOfA = Enum[Enum.A]; // "A"
Hãy nhớ rằng các thành viên chuỗi enum hoàn toàn không có được ánh xạ ngược.
0
hoặc 1
từ enum này? export enum Octave { ZERO = 0, ONE = 1 }
enum Enum {"A"}; let nameOfA = Enum[Enum.A];
? Kể từ typcript@2.9.2, nó hoạt động tốt với tôi ...
Giả sử bạn tuân thủ các quy tắc và chỉ tạo ra các enum với các giá trị số, bạn có thể sử dụng mã này. Điều này xử lý chính xác trường hợp bạn có một tên trùng hợp là một số hợp lệ
enum Color {
Red,
Green,
Blue,
"10" // wat
}
var names: string[] = [];
for(var n in Color) {
if(typeof Color[n] === 'number') names.push(n);
}
console.log(names); // ['Red', 'Green', 'Blue', '10']
Đối với tôi một cách dễ dàng, thiết thực và trực tiếp hơn để hiểu những gì đang diễn ra, đó là bảng liệt kê sau:
enum colors { red, green, blue };
Sẽ được chuyển đổi về cơ bản này:
var colors = { red: 0, green: 1, blue: 2,
[0]: "red", [1]: "green", [2]: "blue" }
Bởi vì điều này, sau đây sẽ là đúng:
colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0
Điều này tạo ra một cách dễ dàng để có được tên của một liệt kê như sau:
var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
Nó cũng tạo ra một cách hay để chuyển đổi một chuỗi thành một giá trị được liệt kê.
var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
Hai tình huống trên là tình huống phổ biến hơn nhiều, bởi vì thông thường bạn quan tâm nhiều hơn đến tên của một giá trị cụ thể và tuần tự hóa các giá trị theo cách chung.
Nếu bạn chỉ tìm kiếm tên và lặp lại sau, sử dụng:
Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];
Object.values(myEnum).filter(value => typeof value === 'string') as string[];
Object.values(myEnum).filter(value => typeof value === 'string').map(key => { return {id: myEnum[key], type: key }; });
Với TypeScript Phiên bản 1.8.9 hiện tại, tôi sử dụng Enums gõ:
export enum Option {
OPTION1 = <any>'this is option 1',
OPTION2 = <any>'this is option 2'
}
với kết quả trong đối tượng Javascript này:
Option = {
"OPTION1": "this is option 1",
"OPTION2": "this is option 2",
"this is option 1": "OPTION1",
"this is option 2": "OPTION2"
}
vì vậy tôi phải truy vấn thông qua các khóa và giá trị và chỉ trả về giá trị:
let optionNames: Array<any> = [];
for (let enumValue in Option) {
let optionNameLength = optionNames.length;
if (optionNameLength === 0) {
this.optionNames.push([enumValue, Option[enumValue]]);
} else {
if (this.optionNames[optionNameLength - 1][1] !== enumValue) {
this.optionNames.push([enumValue, Option[enumValue]]);
}
}
}
Và tôi nhận được các phím tùy chọn trong một mảng:
optionNames = [ "OPTION1", "OPTION2" ];
Kể từ TypeScript 2.4, enums có thể chứa các chuỗi intialators https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
Điều này cho phép bạn viết:
enum Order {
ONE = "First",
TWO = "Second"
}
console.log(`One is ${Order.ONE.toString()}`);
và nhận đầu ra này:
Một là đầu tiên
Một giải pháp thú vị khác được tìm thấy ở đây là sử dụng ES6 Map:
export enum Type {
low,
mid,
high
}
export const TypeLabel = new Map<number, string>([
[Type.low, 'Low Season'],
[Type.mid, 'Mid Season'],
[Type.high, 'High Season']
]);
SỬ DỤNG
console.log(TypeLabel.get(Type.low)); // Low Season
Hãy để ts-enum-util
( github , npm ) thực hiện công việc cho bạn và cung cấp rất nhiều tiện ích an toàn loại bổ sung. Hoạt động với cả enum chuỗi và số, bỏ qua đúng các mục tra cứu ngược chỉ mục số cho enum số:
Chuỗi enum:
import {$enum} from "ts-enum-util";
enum Option {
OPTION1 = 'this is option 1',
OPTION2 = 'this is option 2'
}
// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();
// type: Option[]
// value: ["this is option 1", "this is option 2"]
const values = $enum(Option).getValues();
Số enum:
enum Option {
OPTION1,
OPTION2
}
// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();
// type: Option[]
// value: [0, 1]
const values = $enum(Option).getValues();
Bắt đầu từ TypeScript 2.4, enum sẽ không chứa khóa làm thành viên nữa. nguồn từ readScript Typeme
Thông báo trước là các enum khởi tạo chuỗi không thể được ánh xạ ngược để lấy tên thành viên enum ban đầu. Nói cách khác, bạn không thể viết Màu ["ĐỎ"] để lấy chuỗi "Đỏ".
Giải pháp của tôi:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
Bạn có thể sử dụng enum-values
gói tôi đã viết khi tôi gặp vấn đề tương tự:
var names = EnumValues.getNames(myEnum);
Dựa trên một số câu trả lời ở trên, tôi đã đưa ra chữ ký hàm an toàn loại này:
export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}
Sử dụng:
enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);
loại stringVals
là'entry1' | 'entry2'
(keyof T)[]
thay vì keyof T
. Ngoài ra, các export
sân chơi của bạn dừng hoạt động.
Dường như không có câu trả lời nào ở đây sẽ hoạt động với chuỗi-enums trong strict
-mode.
Hãy xem xét enum như:
enum AnimalEnum {
dog = "dog", cat = "cat", mouse = "mouse"
}
Truy cập này có AnimalEnum["dog"]
thể dẫn đến một lỗi như:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof AnimalEnum'.ts(7053)
.
Giải pháp thích hợp cho trường hợp đó, viết nó như sau:
AnimalEnum["dog" as keyof typeof AnimalEnum]
keyof
với typeof
! Giải pháp khác có vẻ khá mờ nhạt, nhưng sau tất cả, tôi nghĩ rằng Typecript cần tiếp tục cải thiện trên DX - Trải nghiệm dành cho nhà phát triển cho Enum
Theo tài liệu của TypeScript, chúng ta có thể thực hiện điều này thông qua Enum với các hàm tĩnh.
Nhận tên Enum với các hàm tĩnh
enum myEnum {
entry1,
entry2
}
namespace myEnum {
export function GetmyEnumName(m: myEnum) {
return myEnum[m];
}
}
now we can call it like below
myEnum.GetmyEnumName(myEnum.entry1);
// result entry1
để đọc thêm về Enum với chức năng tĩnh, hãy theo liên kết dưới đây https://basarat.gitbooks.io/typescript/docs/enums.html
Giải pháp duy nhất phù hợp với tôi trong mọi trường hợp (ngay cả khi giá trị là chuỗi) là:
var enumToString = function(enumType, enumValue) {
for (var enumMember in enumType) {
if (enumType[enumMember]==enumValue) return enumMember
}
}
Câu hỏi cũ, nhưng, tại sao không sử dụng const
bản đồ đối tượng?
Thay vì làm điều này:
enum Foo {
BAR = 60,
EVERYTHING_IS_TERRIBLE = 80
}
console.log(Object.keys(Foo))
// -> ["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE", 60, 80]
Làm điều này (chú ý đến các as const
diễn viên):
const Foo = {
BAR: 60,
EVERYTHING_IS_TERRIBLE: 80
} as const
console.log(Object.keys(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> [60, 80]
console.log(Object.keys(Foo))
trong ví dụ đầu tiên chỉ trả về ["BAR", "EVERYTHING_IS_TERRIBLE"]
..
["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
Tôi tìm thấy câu hỏi này bằng cách tìm kiếm "TypeScript lặp qua các khóa enum". Vì vậy, tôi chỉ muốn đăng giải pháp phù hợp với tôi trong trường hợp của tôi. Có lẽ nó cũng sẽ giúp được ai đó.
Trường hợp của tôi là như sau: Tôi muốn lặp lại từng khóa enum, sau đó lọc một số khóa, sau đó truy cập một số đối tượng có các khóa là giá trị được tính từ enum. Vì vậy, đây là cách tôi làm mà không có bất kỳ lỗi TS.
enum MyEnum = { ONE = 'ONE', TWO = 'TWO' }
const LABELS = {
[MyEnum.ONE]: 'Label one',
[MyEnum.TWO]: 'Label two'
}
// to declare type is important - otherwise TS complains on LABELS[type]
// also, if replace Object.values with Object.keys -
// - TS blames wrong types here: "string[] is not assignable to MyEnum[]"
const allKeys: Array<MyEnum> = Object.values(MyEnum)
const allowedKeys = allKeys.filter(
(type) => type !== MyEnum.ONE
)
const allowedLabels = allowedKeys.map((type) => ({
label: LABELS[type]
}))
Tôi đã viết một lớp EnumUtil đang thực hiện kiểm tra kiểu theo giá trị enum:
export class EnumUtils {
/**
* Returns the enum keys
* @param enumObj enum object
* @param enumType the enum type
*/
static getEnumKeys(enumObj: any, enumType: EnumType): any[] {
return EnumUtils.getEnumValues(enumObj, enumType).map(value => enumObj[value]);
}
/**
* Returns the enum values
* @param enumObj enum object
* @param enumType the enum type
*/
static getEnumValues(enumObj: any, enumType: EnumType): any[] {
return Object.keys(enumObj).filter(key => typeof enumObj[key] === enumType);
}
}
export enum EnumType {
Number = 'number',
String = 'string'
}
Làm thế nào để sử dụng nó:
enum NumberValueEnum{
A= 0,
B= 1
}
enum StringValueEnum{
A= 'A',
B= 'B'
}
EnumUtils.getEnumKeys(NumberValueEnum, EnumType.number);
EnumUtils.getEnumValues(NumberValueEnum, EnumType.number);
EnumUtils.getEnumKeys(StringValueEnum, EnumType.string);
EnumUtils.getEnumValues(StringValueEnum, EnumType.string);
Kết quả cho các khóa NumberValueEnum: ["A", "B"]
Kết quả cho các giá trị NumberValueEnum: [0, 1]
Kết quả cho StringValueEnumkeys: ["A", "B"]
Kết quả cho StringValueEnumvalues: ["A", "B"]
Tôi thấy giải pháp đó thanh lịch hơn:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
Nó sẽ hiển thị:
bar
foo
Enum của tôi là như thế này:
export enum UserSorting {
SortByFullName = "Sort by FullName",
SortByLastname = "Sort by Lastame",
SortByEmail = "Sort by Email",
SortByRoleName = "Sort by Role",
SortByCreatedAt = "Sort by Creation date",
SortByCreatedBy = "Sort by Author",
SortByUpdatedAt = "Sort by Edit date",
SortByUpdatedBy = "Sort by Editor",
}
Vì vậy, làm điều này trở lại không xác định :
UserSorting[UserSorting.SortByUpdatedAt]
Để giải quyết vấn đề này, tôi chọn một cách khác để thực hiện bằng cách sử dụng ống:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'enumKey'
})
export class EnumKeyPipe implements PipeTransform {
transform(value, args: string[] = null): any {
let enumValue = args[0];
var keys = Object.keys(value);
var values = Object.values(value);
for (var i = 0; i < keys.length; i++) {
if (values[i] == enumValue) {
return keys[i];
}
}
return null;
}
}
Và để sử dụng nó:
return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);
Nếu bạn có enum
enum Diet {
KETO = "Ketogenic",
ATKINS = "Atkins",
PALEO = "Paleo",
DGAF = "Whatever"
}
Sau đó, bạn có thể nhận khóa và giá trị như:
Object.keys(Diet).forEach((d: Diet) => {
console.log(d); // KETO
console.log(Diet[d]) // Ketogenic
});
Argument of type '(d: Diet) => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'. Types of parameters 'd' and 'value' are incompatible. Type 'string' is not assignable to type 'MyEnum'.(2345)
Tôi đã viết một hàm trợ giúp để liệt kê một enum:
static getEnumValues<T extends number>(enumType: {}): T[] {
const values: T[] = [];
const keys = Object.keys(enumType);
for (const key of keys.slice(0, keys.length / 2)) {
values.push(<T>+key);
}
return values;
}
Sử dụng:
for (const enumValue of getEnumValues<myEnum>(myEnum)) {
// do the thing
}
Hàm trả về một cái gì đó có thể dễ dàng liệt kê, và cũng chuyển sang loại enum.
Sử dụng TypeScript phiên bản hiện tại, bạn có thể sử dụng các hàm như thế này để ánh xạ Enum tới bản ghi bạn chọn. Lưu ý rằng bạn không thể xác định các giá trị chuỗi với các hàm này khi chúng tìm các khóa có giá trị là một số.
enum STATES {
LOGIN,
LOGOUT,
}
export const enumToRecordWithKeys = <E extends any>(enumeration: E): E => (
Object.keys(enumeration)
.filter(key => typeof enumeration[key] === 'number')
.reduce((record, key) => ({...record, [key]: key }), {}) as E
);
export const enumToRecordWithValues = <E extends any>(enumeration: E): E => (
Object.keys(enumeration)
.filter(key => typeof enumeration[key] === 'number')
.reduce((record, key) => ({...record, [key]: enumeration[key] }), {}) as E
);
const states = enumToRecordWithKeys(STATES)
const statesWithIndex = enumToRecordWithValues(STATES)
console.log(JSON.stringify({
STATES,
states,
statesWithIndex,
}, null ,2));
// Console output:
{
"STATES": {
"0": "LOGIN",
"1": "LOGOUT",
"LOGIN": 0,
"LOGOUT": 1
},
"states": {
"LOGIN": "LOGIN",
"LOGOUT": "LOGOUT"
},
"statesWithIndex": {
"LOGIN": 0,
"LOGOUT": 1
}
}
Đã có rất nhiều câu trả lời ở đây nhưng tôi nghĩ rằng tôi sẽ ném giải pháp của mình lên ngăn xếp.
enum AccountType {
Google = 'goo',
Facebook = 'boo',
Twitter = 'wit',
}
type Key = keyof typeof AccountType // "Google" | "Facebook" | "Twitter"
// this creates a POJO of the enum "reversed" using TypeScript's Record utility
const reversed = (Object.keys(AccountType) as Key[]).reduce((acc, key) => {
acc[AccountType[key]] = key
return acc
}, {} as Record<AccountType, string>)
Cho rõ ràng:
/*
* reversed == {
* "goo": "Google",
* "boo": "Facebook",
* "wit": "Twitter",
* }
* reversed[AccountType.Google] === "Google" 👍
*/
Tham chiếu cho bản ghi TypeScript
Một chức năng trợ giúp tốt đẹp:
const getAccountTypeName = (type: AccountType) => {
return reversed[type]
};
// getAccountTypeName(AccountType.Twitter) === 'Twitter'
Nó không phải là câu trả lời chính xác cho câu hỏi của bạn nhưng nó là một mẹo để giải quyết vấn đề của bạn.
export module Gender {
export enum Type {
Female = 1,
Male = 2
};
export const List = Object.freeze([
Type[Type.Female] ,
Type[Type.Male]
]);
}
Bạn có thể mở rộng mô hình danh sách của bạn theo cách bạn muốn.
export const List = Object.freeze([
{ name: Type[Type.Female], value: Type.Female } ,
{ name: Type[Type.Male], value: Type.Male }
]);
Bây giờ, bạn có thể sử dụng nó theo cách này:
for(const gender of Gender.List){
console.log(gender.name);
console.log(gender.value);
}
hoặc là:
if(i === Gender.Type.Male){
console.log("I am a man.");
}
getAllEnumValues
vàgetAllEnumKeys
cho mục đích của bạn