回答:
投稿したコードは機能します。列挙型メンバーの値を含む、列挙型のすべてのメンバーを出力します。たとえば、次のコード:
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は列挙型をJSオブジェクトにコンパイルし、列挙型の値はオブジェクトのメンバーです。TSが将来的に別の方法で実装することを決定した場合、上記の手法は失敗する可能性があります。
答えはすでに提供されていますが、ほとんど誰もドキュメントを指さしていません
これがスニペットです
enum Enum {
A
}
let nameOfA = Enum[Enum.A]; // "A"
文字列列挙型メンバーは、逆マッピングをまったく生成しないことに注意してください。
0
または1
この列挙型からどうですか?export enum Octave { ZERO = 0, ONE = 1 }
enum Enum {"A"}; let nameOfA = Enum[Enum.A];
ですか?typescript@2.9.2以降は、私にとっては問題なく動作します...
規則を守り、数値の列挙のみを生成すると仮定すると、このコードを使用できます。これは、偶然に有効な番号である名前がある場合を正しく処理します
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]);
また、文字列を列挙値に変換するための優れた方法も作成します。
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[];
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では、型付きのEnumを使用します。
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" ];
TypeScript 2.4以降、列挙型には文字列初期化子を含めることができます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()}`);
この出力を取得します:
1つは最初
Let 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();
TypeScript 2.4以降では、enumにはキーがメンバーとして含まれなくなりました。TypeScript readmeからのソース
注意点は、文字列で初期化された列挙型を逆マッピングして、元の列挙型メンバー名を取得することはできないということです。つまり、Colors ["RED"]を記述して文字列「Red」を取得することはできません。
私の解決策:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
上記のいくつかの回答に基づいて、このタイプセーフな関数シグネチャを思いつきました。
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
遊び場が機能しなくなります。
strict
-modeのstring-enumsでは、ここでの答えはどれも機能しないようです。
列挙型を次のように考えてください:
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ドキュメントによると、静的関数を使用して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は列挙型キーを反復処理する」を検索してこの質問を見つけました。だから私は私の場合にうまくいく解決策を投稿したいだけです。多分それは誰かにも役立ちます。
私の場合は次のとおりです。各列挙型キーを反復処理し、いくつかのキーをフィルター処理してから、列挙型から計算された値としてキーを持つオブジェクトにアクセスします。これが、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クラスを作成しました。
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キーの結果:["A"、 "B"]
NumberValueEnum値の結果:[0、1]
StringValueEnumkeysの結果:["A"、 "B"]
StringValueEnumvaluesの結果:["A"、 "B"]
私はその解決策がよりエレガントであると思います:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
表示されます:
bar
foo
私の列挙型は次のとおりです:
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]
この問題を解決するには、パイプを使用して別の方法を選択します。
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 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)
列挙型を列挙するヘルパー関数を書きました:
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
}
この関数は、簡単に列挙できるものを返し、列挙型にキャストします。
現在のバージョンの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'
それはあなたの質問の正確な答えではありませんが、あなたの問題に取り組むためのトリックです。
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
あなたの目的のために