Saya ingin mengulang jenis TypeScript enumdan mendapatkan setiap nama simbol yang disebutkan, misalnya:
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Saya ingin mengulang jenis TypeScript enumdan mendapatkan setiap nama simbol yang disebutkan, misalnya:
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Jawaban:
Kode yang Anda poskan akan berfungsi; itu akan mencetak semua anggota enum, termasuk nilai-nilai anggota enum. Misalnya, kode berikut:
enum myEnum { bar, foo }
for (var enumMember in myEnum) {
console.log("enum member: ", enumMember);
}
Akan mencetak yang berikut:
Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo
Jika Anda hanya menginginkan nama anggota saja, dan bukan nilainya, Anda dapat melakukan sesuatu seperti ini:
for (var enumMember in myEnum) {
var isValueProperty = parseInt(enumMember, 10) >= 0
if (isValueProperty) {
console.log("enum member: ", myEnum[enumMember]);
}
}
Itu akan mencetak hanya nama-nama:
Anggota Enum: bar
Anggota Enum: foo
Peringatan: ini sedikit bergantung pada detail implementasi: TypeScript mengkompilasi enum ke objek JS dengan nilai enum menjadi anggota objek. Jika TS memutuskan untuk menerapkannya secara berbeda di masa depan, teknik di atas bisa pecah.
+enumMember >= 0seharusnya isFinite(+enumMember)karena nilai negatif atau floating point dipetakan terbalik juga. ( Taman bermain )
Meskipun jawabannya sudah disediakan, Hampir tidak ada yang menunjuk ke dokumen
Ini cuplikan
enum Enum {
A
}
let nameOfA = Enum[Enum.A]; // "A"
Perlu diingat bahwa anggota string enum tidak mendapatkan pemetaan terbalik yang dihasilkan sama sekali.
0atau 1dari enum ini? export enum Octave { ZERO = 0, ONE = 1 }
enum Enum {"A"}; let nameOfA = Enum[Enum.A];? Pada typescript@2.9.2 berfungsi dengan baik untuk saya ...
Dengan asumsi Anda mematuhi aturan dan hanya menghasilkan enum dengan nilai numerik, Anda dapat menggunakan kode ini. Ini dengan benar menangani kasus di mana Anda memiliki nama yang secara kebetulan merupakan nomor yang valid
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']
Bagi saya cara yang lebih mudah, praktis dan langsung untuk memahami apa yang sedang terjadi, adalah dengan cara penghitungan berikut:
enum colors { red, green, blue };
Pada dasarnya akan dikonversi menjadi ini:
var colors = { red: 0, green: 1, blue: 2,
[0]: "red", [1]: "green", [2]: "blue" }
Karena itu, yang berikut ini akan benar:
colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0
Ini menciptakan cara mudah untuk mendapatkan nama yang disebutkan sebagai berikut:
var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
Itu juga menciptakan cara yang bagus untuk mengonversi string ke nilai yang disebutkan.
var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
Dua situasi di atas adalah situasi yang jauh lebih umum, karena biasanya Anda jauh lebih tertarik pada nama nilai tertentu dan membuat cerita bersambung dengan cara yang umum.
Jika Anda hanya mencari nama dan beralih lagi gunakan:
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 }; });
Dengan TypeScript Versi 1.8.9 yang sekarang saya gunakan mengetikkan Enums:
export enum Option {
OPTION1 = <any>'this is option 1',
OPTION2 = <any>'this is option 2'
}
dengan hasil dalam objek Javascript ini:
Option = {
"OPTION1": "this is option 1",
"OPTION2": "this is option 2",
"this is option 1": "OPTION1",
"this is option 2": "OPTION2"
}
jadi saya harus mencari melalui kunci dan nilai dan hanya mengembalikan nilai:
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]]);
}
}
}
Dan saya menerima tombol opsi dalam Array:
optionNames = [ "OPTION1", "OPTION2" ];
Pada TypeScript 2.4, enum dapat berisi intializers string https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
Ini memungkinkan Anda untuk menulis:
enum Order {
ONE = "First",
TWO = "Second"
}
console.log(`One is ${Order.ONE.toString()}`);
dan dapatkan output ini:
Pertama adalah Pertama
Solusi menarik lain yang ditemukan di sini adalah menggunakan 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']
]);
MENGGUNAKAN
console.log(TypeLabel.get(Type.low)); // Low Season
Biarkan ts-enum-util( github , npm ) melakukan pekerjaan untuk Anda dan menyediakan banyak utilitas tipe-aman tambahan. Bekerja dengan string dan enum numerik, dengan benar mengabaikan entri numerik indeks pencarian terbalik untuk enum numerik:
String 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();
Angka numerik:
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();
Mulai dari TypeScript 2.4, enum tidak akan berisi kunci sebagai anggota lagi. sumber dari readScript TypeScript
Peringatannya adalah bahwa enum yang diinisialisasi string tidak dapat dipetakan terbalik untuk mendapatkan nama anggota enum yang asli. Dengan kata lain, Anda tidak dapat menulis Warna ["RED"] untuk mendapatkan string "Merah".
Solusi saya:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
Anda dapat menggunakan enum-valuespaket yang saya tulis ketika saya memiliki masalah yang sama:
var names = EnumValues.getNames(myEnum);
Berdasarkan beberapa jawaban di atas, saya menemukan tanda tangan fungsi aman-jenis ini:
export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}
Pemakaian:
enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);
jenis stringValsyaitu'entry1' | 'entry2'
(keyof T)[]sebagai ganti keyof T. Juga, exportberhenti bermain Anda dari bekerja.
Tampaknya tidak ada jawaban di sini yang akan bekerja dengan string-enums di strict-mode.
Pertimbangkan enum sebagai:
enum AnimalEnum {
dog = "dog", cat = "cat", mouse = "mouse"
}
Mengakses ini dengan AnimalEnum["dog"]dapat mengakibatkan kesalahan seperti:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof AnimalEnum'.ts(7053).
Solusi yang tepat untuk kasus itu, tulis sebagai:
AnimalEnum["dog" as keyof typeof AnimalEnum]
keyofdengan typeof! Solusi lain tampaknya cukup buram, tetapi bagaimanapun juga saya pikir Typescript perlu terus meningkatkan DX - Pengalaman Pengembang untuk Enum
Cara terbaik yang saya pikirkan adalah dengan mendeklarasikan nilai enum yang diinginkan. Dengan cara mengaksesnya bersih dan cantik (setiap saat).
enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }
for (var entry in myEnum) {
console.log(entry);
}
akan menghasilkan:
VALUE1
VALUE2
Menurut dokumentasi TypeScript, kita dapat melakukan ini melalui Enum dengan fungsi statis.
Dapatkan Nama Enum dengan fungsi statis
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
untuk membaca lebih lanjut tentang Enum dengan fungsi statis ikuti tautan di bawah ini https://basarat.gitbooks.io/typescript/docs/enums.html
Satu-satunya solusi yang bekerja untuk saya dalam semua kasus (meskipun nilai adalah string) adalah sebagai berikut:
var enumToString = function(enumType, enumValue) {
for (var enumMember in enumType) {
if (enumType[enumMember]==enumValue) return enumMember
}
}
Pertanyaan lama, tetapi, mengapa tidak menggunakan constpeta objek?
Alih-alih melakukan ini:
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]
Lakukan ini (perhatikan para as constpemain):
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))dalam contoh pertama hanya mengembalikan ["BAR", "EVERYTHING_IS_TERRIBLE"]..
["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
Saya menemukan pertanyaan ini dengan mencari "TypeScript iterate over enum keys". Jadi saya hanya ingin memposting solusi yang cocok untuk saya dalam kasus saya. Mungkin itu akan membantu seseorang juga.
Kasus saya adalah sebagai berikut: Saya ingin mengulangi setiap kunci enum, lalu menyaring beberapa kunci, lalu mengakses beberapa objek yang memiliki kunci sebagai nilai yang dihitung dari enum. Jadi ini adalah bagaimana saya melakukannya tanpa ada kesalahan 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]
}))
Saya menulis kelas EnumUtil yang membuat pemeriksaan tipe dengan nilai 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'
}
Bagaimana cara menggunakannya:
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);
Hasil untuk kunci NumberValueEnum: ["A", "B"]
Hasil untuk nilai-nilai NumberValueEnum: [0, 1]
Hasil untuk StringValueEnumkeys: ["A", "B"]
Hasil untuk StringValueEnumvalues: ["A", "B"]
Saya menemukan solusi itu lebih elegan:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
Ini menampilkan:
bar
foo
Enum saya seperti ini:
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",
}
jadi pengembalian ini tidak ditentukan :
UserSorting[UserSorting.SortByUpdatedAt]
Untuk mengatasi masalah ini, saya memilih cara lain untuk melakukannya menggunakan Pipa:
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;
}
}
Dan untuk menggunakannya:
return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);
Jika Anda memiliki enum
enum Diet {
KETO = "Ketogenic",
ATKINS = "Atkins",
PALEO = "Paleo",
DGAF = "Whatever"
}
Maka Anda bisa mendapatkan kunci dan nilai-nilai seperti:
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)
Saya menulis fungsi pembantu untuk menyebutkan 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;
}
Pemakaian:
for (const enumValue of getEnumValues<myEnum>(myEnum)) {
// do the thing
}
Fungsi mengembalikan sesuatu yang dapat dengan mudah disebutkan, dan juga dilemparkan ke tipe enum.
Menggunakan versi saat ini TypeScript Anda dapat menggunakan fungsi seperti ini untuk memetakan Enum ke catatan pilihan Anda. Perhatikan bahwa Anda tidak dapat menentukan nilai string dengan fungsi-fungsi ini karena mereka mencari kunci dengan nilai yang merupakan angka.
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
}
}
Sudah ada banyak jawaban di sini, tetapi saya kira saya akan membuang solusi saya ke tumpukan.
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>)
Untuk kejelasan:
/*
* reversed == {
* "goo": "Google",
* "boo": "Facebook",
* "wit": "Twitter",
* }
* reversed[AccountType.Google] === "Google" 👍
*/
Referensi untuk Record TypeScript
Fungsi pembantu yang bagus:
const getAccountTypeName = (type: AccountType) => {
return reversed[type]
};
// getAccountTypeName(AccountType.Twitter) === 'Twitter'
Ini bukan jawaban tepat atas pertanyaan Anda, tetapi itu adalah trik untuk mengatasi masalah Anda.
export module Gender {
export enum Type {
Female = 1,
Male = 2
};
export const List = Object.freeze([
Type[Type.Female] ,
Type[Type.Male]
]);
}
Anda dapat memperluas model daftar dengan cara yang Anda inginkan.
export const List = Object.freeze([
{ name: Type[Type.Female], value: Type.Female } ,
{ name: Type[Type.Male], value: Type.Male }
]);
Sekarang, Anda dapat menggunakannya dengan cara ini:
for(const gender of Gender.List){
console.log(gender.name);
console.log(gender.value);
}
atau:
if(i === Gender.Type.Male){
console.log("I am a man.");
}
getAllEnumValuesdangetAllEnumKeysuntuk tujuan Anda