ฉันต้องการย้ำ TypeScript เป็นenum
ประเภทและรับชื่อสัญลักษณ์ที่แจกแจงเช่น
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
ฉันต้องการย้ำ TypeScript เป็นenum
ประเภทและรับชื่อสัญลักษณ์ที่แจกแจงเช่น
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
คำตอบ:
รหัสที่คุณโพสต์จะใช้งานได้ มันจะพิมพ์สมาชิกทั้งหมดของ enum รวมถึงค่าของสมาชิก enum ตัวอย่างเช่นรหัสต่อไปนี้:
enum myEnum { bar, foo }
for (var enumMember in myEnum) {
console.log("enum member: ", enumMember);
}
จะพิมพ์ดังต่อไปนี้:
Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo
หากคุณต้องการเฉพาะชื่อสมาชิก แต่ไม่ใช่ค่าคุณสามารถทำสิ่งนี้:
for (var enumMember in myEnum) {
var isValueProperty = parseInt(enumMember, 10) >= 0
if (isValueProperty) {
console.log("enum member: ", myEnum[enumMember]);
}
}
ที่จะพิมพ์ออกมาเพียงชื่อ:
สมาชิก Enum: บาร์
สมาชิก Enum: foo
Caveat: สิ่งนี้ขึ้นอยู่กับรายละเอียดการนำไปใช้งานเล็กน้อย: คอมไพเลอร์ TypeScript enums กับวัตถุ JS ที่มีค่า enum เป็นสมาชิกของวัตถุ หาก TS ตัดสินใจที่จะใช้พวกเขาแตกต่างกันในอนาคตเทคนิคดังกล่าวอาจแตกหักได้
+enumMember >= 0
ควรจะเป็นisFinite(+enumMember)
เพราะค่าลบหรือจุดลอยได้รับการแมปกลับเกินไป ( สนามเด็กเล่น )
แม้ว่าจะได้รับคำตอบแล้ว แต่ก็แทบไม่มีใครชี้ไปที่เอกสาร
นี่คือตัวอย่าง
enum Enum {
A
}
let nameOfA = Enum[Enum.A]; // "A"
โปรดทราบว่าสมาชิกสตริง enum ไม่ได้รับการแม็พย้อนกลับที่สร้างขึ้นเลย
0
หรือ1
จาก enum นี้ export enum Octave { ZERO = 0, ONE = 1 }
enum Enum {"A"}; let nameOfA = Enum[Enum.A];
? ในฐานะของ typescript@2.9.2 มันใช้งานได้ดีสำหรับฉัน ...
สมมติว่าคุณติดกับกฎและสร้าง enums ด้วยค่าตัวเลขเท่านั้นคุณสามารถใช้รหัสนี้ สิ่งนี้จะจัดการกรณีที่คุณมีชื่อที่เป็นตัวเลขที่ถูกต้องโดยบังเอิญ
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']
สำหรับฉันวิธีที่ง่ายกว่าในทางปฏิบัติและตรงไปตรงมาเพื่อทำความเข้าใจสิ่งที่เกิดขึ้นคือการแจงนับต่อไปนี้:
enum colors { red, green, blue };
จะถูกแปลงเป็นหลักในเรื่องนี้:
var colors = { red: 0, green: 1, blue: 2,
[0]: "red", [1]: "green", [2]: "blue" }
ด้วยเหตุนี้สิ่งต่อไปนี้จะเป็นจริง:
colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0
สิ่งนี้สร้างวิธีที่ง่ายในการรับชื่อของ enum
var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
นอกจากนี้ยังสร้างวิธีที่ดีในการแปลงสตริงเป็นค่าที่แจกแจง
var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
สถานการณ์ทั้งสองข้างต้นเป็นสถานการณ์ที่พบได้บ่อยกว่าเนื่องจากคุณมักจะสนใจชื่อของค่าเฉพาะและค่าการทำให้เป็นอันดับในแบบทั่วไป
หากคุณค้นหาเฉพาะชื่อและวนซ้ำในภายหลังให้ใช้:
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 }; });
ด้วย TypeScript ปัจจุบันรุ่น 1.8.9 ฉันใช้ Enums พิมพ์:
export enum Option {
OPTION1 = <any>'this is option 1',
OPTION2 = <any>'this is option 2'
}
ด้วยผลลัพธ์ในวัตถุ Javascript นี้:
Option = {
"OPTION1": "this is option 1",
"OPTION2": "this is option 2",
"this is option 1": "OPTION1",
"this is option 2": "OPTION2"
}
ดังนั้นฉันต้องค้นหาคีย์และค่าและคืนค่าเท่านั้น:
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]]);
}
}
}
และฉันได้รับปุ่มตัวเลือกใน Array:
optionNames = [ "OPTION1", "OPTION2" ];
ในฐานะของ TypeScript 2.4, enums สามารถมี intializers สตริงได้https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
อนุญาตให้คุณเขียน:
enum Order {
ONE = "First",
TWO = "Second"
}
console.log(`One is ${Order.ONE.toString()}`);
และรับผลลัพธ์นี้:
หนึ่งคือก่อน
วิธีนี้ใช้ได้ผลเช่นกัน
enum ScreenType {
Edit = 1,
New = 2,
View = 4
}
var type: ScreenType = ScreenType.Edit;
console.log(ScreenType[type]); //Edit
อีกวิธีแก้ปัญหาที่น่าสนใจที่นี่คือการใช้แผนที่ ES6:
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']
]);
ใช้
console.log(TypeLabel.get(Type.low)); // Low Season
ให้ts-enum-util
( github , npm ) ทำงานให้คุณและจัดเตรียมโปรแกรมอรรถประโยชน์ที่ปลอดภัยสำหรับการพิมพ์เพิ่มเติมจำนวนมาก ทำงานกับทั้งสตริงและตัวเลข enums อย่างถูกต้องละเว้นรายการตัวเลขดัชนีย้อนกลับค้นหาสำหรับ enums ตัวเลข:
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();
ตัวเลข 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();
เริ่มจาก TypeScript 2.4, enum จะไม่มีคีย์เป็นสมาชิกอีกต่อไป แหล่งที่มาจาก ReadScript ของ TypeScript
ข้อแม้คือ enums สตริงที่เริ่มต้นไม่สามารถย้อนกลับแมปที่จะได้รับชื่อสมาชิก enum เดิม คุณไม่สามารถเขียนสี ["RED"] เพื่อรับสตริง "Red"
ทางออกของฉัน:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
คุณสามารถใช้enum-values
แพ็คเกจที่ฉันเขียนเมื่อฉันมีปัญหาเดียวกัน:
var names = EnumValues.getNames(myEnum);
จากคำตอบบางข้อข้างต้นฉันพบกับลายเซ็นฟังก์ชั่นเซฟตี้ประเภทนี้:
export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}
การใช้งาน:
enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);
ประเภทของstringVals
คือ'entry1' | 'entry2'
(keyof T)[]
keyof T
นอกจากนี้export
สนามเด็กเล่นของคุณหยุดทำงาน
ดูเหมือนว่าไม่มีคำตอบใด ๆ ที่นี่จะทำงานกับ string-enums ในstrict
- โหมด
พิจารณา enum เป็น:
enum AnimalEnum {
dog = "dog", cat = "cat", mouse = "mouse"
}
การเข้าถึงสิ่งนี้ด้วยAnimalEnum["dog"]
อาจทำให้เกิดข้อผิดพลาดเช่น:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof AnimalEnum'.ts(7053)
.
วิธีแก้ปัญหาที่เหมาะสมสำหรับกรณีนั้นเขียนเป็น:
AnimalEnum["dog" as keyof typeof AnimalEnum]
keyof
กับtypeof
! วิธีการแก้ปัญหาอื่น ๆ ดูเหมือนจะค่อนข้างทึบ แต่หลังจากทั้งหมดฉันคิดว่า typescript ต้องปรับปรุงบน DX - ประสบการณ์นักพัฒนาสำหรับ Enum
วิธีที่ดีที่สุดที่ฉันคิดคือการประกาศค่า enum ที่ต้องการ วิธีการเข้าถึงพวกเขานั้นสะอาดและน่ารัก (ทุกครั้ง)
enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }
for (var entry in myEnum) {
console.log(entry);
}
จะผลิต:
VALUE1
VALUE2
ตามเอกสารประกอบของ TypeScript เราสามารถทำได้ผ่าน Enum ด้วยฟังก์ชั่นคงที่
รับชื่อ Enum ด้วยฟังก์ชั่นคงที่
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
สำหรับการอ่านเพิ่มเติมเกี่ยวกับ Enum พร้อมฟังก์ชั่นสแตติกตามลิงค์ด้านล่าง https://basarat.gitbooks.io/typescript/docs/enums.html
ทางออกเดียวที่ใช้ได้สำหรับฉันในทุกกรณี(แม้ว่าค่าเป็นสตริง)มีดังต่อไปนี้:
var enumToString = function(enumType, enumValue) {
for (var enumMember in enumType) {
if (enumType[enumMember]==enumValue) return enumMember
}
}
คำถามเก่า แต่ทำไมไม่ใช้const
แผนที่วัตถุ
แทนที่จะทำสิ่งนี้:
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]
ทำสิ่งนี้ (ให้ความสนใจกับas const
นักแสดง):
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))
ในตัวอย่างแรกเพียงผลตอบแทน["BAR", "EVERYTHING_IS_TERRIBLE"]
..
["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
ฉันพบคำถามนี้ด้วยการค้นหา "TypeScript ทำซ้ำผ่านคีย์ enum" ดังนั้นฉันแค่ต้องการโพสต์โซลูชั่นที่เหมาะกับฉันในกรณีของฉัน บางทีมันอาจจะช่วยให้ใครบางคนเช่นกัน
เคสของฉันมีดังต่อไปนี้: ฉันต้องการวนซ้ำทุกคีย์ enum แล้วกรองบางคีย์จากนั้นเข้าถึงวัตถุบางอย่างที่มีคีย์เป็นค่าที่คำนวณได้จาก enum นี่คือวิธีที่ฉันทำโดยไม่มีข้อผิดพลาด 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]
}))
ฉันเขียนคลาส EnumUtil ซึ่งทำการตรวจสอบชนิดโดยค่า 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'
}
วิธีใช้งาน:
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);
ผลลัพธ์สำหรับ NumberValueEnum keys: ["A", "B"]
ผลลัพธ์สำหรับค่า NumberValueEnum: [0, 1]
ผลลัพธ์สำหรับ StringValueEnumkeys: ["A", "B"]
ผลลัพธ์สำหรับ StringValueEnumues: ["A", "B"]
ฉันพบว่าวิธีการแก้ปัญหาที่สง่างามมากขึ้น:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
มันแสดง:
bar
foo
Enum ของฉันเป็นเช่นนี้:
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",
}
ดังนั้นการทำเช่นนี้ส่งคืนไม่ได้กำหนด :
UserSorting[UserSorting.SortByUpdatedAt]
ในการแก้ไขปัญหานี้ฉันเลือกวิธีอื่นในการใช้ Pipe:
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;
}
}
และใช้มัน:
return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);
หากคุณมี enum
enum Diet {
KETO = "Ketogenic",
ATKINS = "Atkins",
PALEO = "Paleo",
DGAF = "Whatever"
}
จากนั้นคุณสามารถรับรหัสและค่าเช่น:
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)
ฉันเขียนฟังก์ชันตัวช่วยเพื่อระบุ 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;
}
การใช้งาน:
for (const enumValue of getEnumValues<myEnum>(myEnum)) {
// do the thing
}
ฟังก์ชั่นส่งกลับบางสิ่งที่สามารถระบุได้ง่ายและมันจะแปลงเป็นชนิด enum
การใช้ TypeScript เวอร์ชันปัจจุบันคุณสามารถใช้ฟังก์ชั่นเช่นนี้เพื่อแมป Enum กับบันทึกที่คุณเลือก โปรดทราบว่าคุณไม่สามารถกำหนดค่าสตริงด้วยฟังก์ชั่นเหล่านี้ในขณะที่พวกเขามองหากุญแจที่มีค่าที่เป็นตัวเลข
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
}
}
มีคำตอบมากมายอยู่แล้วที่นี่ แต่ฉันคิดว่าฉันจะโยนคำตอบลงบนสแต็ค
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>)
สำหรับความชัดเจน:
/*
* reversed == {
* "goo": "Google",
* "boo": "Facebook",
* "wit": "Twitter",
* }
* reversed[AccountType.Google] === "Google" 👍
*/
การอ้างอิงสำหรับบันทึก TypeScript
ฟังก์ชั่นผู้ช่วยที่ดี:
const getAccountTypeName = (type: AccountType) => {
return reversed[type]
};
// getAccountTypeName(AccountType.Twitter) === 'Twitter'
ในการรับรายการค่า enum ที่คุณต้องใช้:
enum AnimalEnum {
DOG = "dog",
CAT = "cat",
MOUSE = "mouse"
}
Object.values(AnimalEnum);
มันไม่ได้เป็นคำตอบที่แน่นอนสำหรับคำถามของคุณ แต่มันเป็นเคล็ดลับในการจัดการปัญหาของคุณ
export module Gender {
export enum Type {
Female = 1,
Male = 2
};
export const List = Object.freeze([
Type[Type.Female] ,
Type[Type.Male]
]);
}
คุณสามารถขยายรูปแบบรายการของคุณในแบบที่คุณต้องการ
export const List = Object.freeze([
{ name: Type[Type.Female], value: Type.Female } ,
{ name: Type[Type.Male], value: Type.Male }
]);
ตอนนี้คุณสามารถใช้วิธีนี้:
for(const gender of Gender.List){
console.log(gender.name);
console.log(gender.value);
}
หรือ:
if(i === Gender.Type.Male){
console.log("I am a man.");
}
getAllEnumValues
และgetAllEnumKeys
สำหรับจุดประสงค์ของคุณ