TypeScriptをenum
型として繰り返し、列挙された各シンボル名を取得します。
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
あなたが投稿したコードはうまくいきます。列挙型メンバーの値を含む、列挙型のすべてのメンバーを印刷します。たとえば、次のようなコードです。
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]);
}
}
これは名前だけを表示します。
列挙型メンバー:bar
列挙型メンバー:foo
警告:これは実装の詳細に多少依存します。TypeScriptはenum値をオブジェクトのメンバーにして、enumをJSオブジェクトにコンパイルします。 TSが将来それらを異なって実装することを決定した場合、上記の手法は破綻する可能性があります。
あなたが規則に固執し、数値を含むenumのみを生成すると仮定すると、あなたはこのコードを使うことができます。これは、あなたが偶然にも有効な番号である名前を持っている場合を正しく処理します。
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
これにより、列挙型の名前を次のように簡単に取得できます。
var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
また、文字列を列挙値に変換するためのNice方法も作成されます。
var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
上記の2つの状況は、はるかに一般的な状況です。通常は、特定の値の名前と一般的な方法での値のシリアル化にはるかに関心があるためです。
名前だけを検索して後で繰り返す場合は、次のようにします。
Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];
現在のTypeScriptバージョン1.8.9では、型付き列挙型を使用しています。
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]]);
}
}
}
そして、私は配列でオプションキーを受け取ります:
optionNames = [ "OPTION1", "OPTION2" ];
この解決策もうまくいきます。
enum ScreenType {
Edit = 1,
New = 2,
View = 4
}
var type: ScreenType = ScreenType.Edit;
console.log(ScreenType[type]); //Edit
TypeScript 2.4以降、enumは文字列初期化子 を含むことができます。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()}`);
そして、この出力を取得してください:
一つは最初です
上記のいくつかの回答に基づいて、このタイプセーフな関数シグネチャを思い付きました。
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'
です
TypeScript 2.4からは、列挙型にはキーがもうメンバとして含まれなくなりました。 TypeScriptのreadmeからの ソース
注意点は、文字列で初期化されたenumを元のenumメンバー名を取得するために逆マッピングすることはできないということです。つまり、文字列 "Red"を取得するためにColors ["RED"]を書くことはできません。
私の解決策:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
ts-enum-util
( github 、 npm )があなたのために仕事をして提供しましょう追加のタイプセーフなユーティリティがたくさんあります。文字列と数値の両方の列挙型で動作します。数値型列挙体の数値インデックスの逆引き参照エントリは正しく無視されます。
文字列の列挙:
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 Option {
OPTION1,
OPTION2
}
// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();
// type: Option[]
// value: [0, 1]
const values = $enum(Option).getValues();
ここに設立された別の興味深い解決方法は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']
]);
つかいます
console.log(TypeLabel.get(Type.low)); // Low Season
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
私が考える最良の方法は、目的の列挙値を宣言するだけです。そのようにそれらにアクセスすることはきれいできれいです(毎回)。
enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }
for (var entry in myEnum) {
console.log(entry);
}
生成されます:
VALUE1
VALUE2
Enum値で型チェックをするEnumUtilクラスを書きました。
export class EnumUtils {
/**
* Returns the enum keys
* @param enumObj enum object
*/
static getEnumKeys(enumObj: any, valueType: string): any[] {
return EnumUtils.getEnumValues(enumObj, valueType).map(value => enumObj[value]);
}
/**
* Returns the enum values
* @param enumObj enum object
*/
static getEnumValues(enumObj: any, valueType: string): any[] {
return Object.keys(enumObj).filter(key => typeof enumObj[key] === valueType);
}
}
どうやって使うのですか:
enum TestEnum{
A= 0,
B= 1
}
EnumUtils.getEnumKeys(TestEnum, "number");
EnumUtils.getEnumValues(TestEnum, "number");
キーに対する結果:["A"、 "B"]
値の結果:[0、1]
すべての場合(値が文字列であっても)で唯一の解決策は次のとおりです。
var enumToString = function(enumType, enumValue) {
for (var enumMember in enumType) {
if (enumType[enumMember]==enumValue) return enumMember
}
}
私はその解決策がより洗練されていると思います:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
表示されます。
bar
foo
私はこの質問に「TypeScript iterate over enum keys」を検索しました。だから私は私の場合私のために働く解決策を投稿したいだけです。多分それは誰かにも役立つでしょう。
私の場合は次のとおりです。各列挙キーを反復処理し、次にいくつかのキーをフィルター処理してから、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 !== InsuranceType.OSAGO
)
const allowedLabels = allowedKeys.map((type) => ({
label: LABELS[type]
}))
私の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",
}
そのため、このようにしてundefinedを返します。
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]);