簡體   English   中英

TypeScript映射枚舉

[英]TypeScript mapping enum

在我的應用程序中,我們致力於模擬和真實REST數據的混合。 在TypeScript中,為方便起見,我定義了一堆枚舉。

當我用數據創建任何一種模擬數組時,我使用以下約束:

enum MyEnum { 'myEnumValue1' = 0, myEnumValue2 } 
(...)
 enumField: MyEnum.myEnumValue1,
(...)

TypeScript有效地解決了以下問題:

(...)
enumField: 1,
(...)

但是,通過我的REST API,我將收到與它們的字符串表示形式相同的枚舉集。 可以通過以下兩種方式進行轉換:

MyEnum['string'] => number
MyEnum[number] => string

MyEnum['myEnumValue1'] => 0
MyEnum[0] => 'myEnumValue1'

是否可以生成通用類來以優美的方式處理此轉換,類似於Stack Community在此問題中向我提出的建議

您可以創建類似於對象的函數:

// Return type is a bit more tricky because we have to get the enum type from typeof enum
function fromValue<T>(o: T, value: string): { [P in keyof T]: T[P]  }[keyof T]{
    return  (o as any)[value]; // No type safety here unfrotunately
}

var value = fromValue(MyEnum, ""); //value will be of type MyEnum

除了Titan的完美答案外,這還需要一些調整,以兩種方式來處理您希望從/映射到什么類型的值(字符串或數字)以及想要什么統一的結果(字符串或數字):

enum MyEnum {
    'VAL_ONE' = 0,
    'VAL_TWO' = 1
}

function fromValuetoNumber<T>(o: T, value: string | number): {[P in keyof T]: T[P]} {
    if (typeof (value) === 'string') {
        return  (o as T)[value]; 
    } else if (typeof (value) === 'number') {
        return (o as T)[o[value]]
    }   
}

function fromValueToString<T>(o: T, value: string | number): {[P in keyof T]: T[P]} {
    if (typeof (value) === 'string') {
        return  (o as T)[o[value]]; 
    } else if (typeof (value) === 'number') {
        return (o as T)[value]
    }   
}

console.log(fromValuetoNumber(MyEnum, 'VAL_ONE'))
console.log(fromValuetoNumber(MyEnum, 0))

console.log(fromValueToString(MyEnum, 'VAL_ONE'))
console.log(fromValueToString(MyEnum, 0))

唯一令我困擾的是事實,即如果將泛型分配,TypeScript就會發瘋:

fromValueToString<MyEnum>(MyEnum, 'VAL_ONE')

不過,這只是原始答案的補充。

如何使用string literals而不是枚舉?

我猜您正在使用enums來避免輸入錯誤,並且您希望TypeScript為您“捕獲”它。 因此,如果您使用string literals ,則可以安全輸入,並且將使用相同的“語言”與服務器對話

例如:

export type Sex = 'male' | 'female';
var sex: Sex = 'mela'; // Typo => ERROR from typescript

使用ts-enum-utilgithubnpm ),您可以通過運行時驗證在枚舉值和名稱(沿任一方向)之間執行類型安全的轉換。 如果在運行時遇到無效值,則可以選擇引發錯誤或返回默認值(默認情況下未定義)的方法變體。

例:

import {$enum} from "ts-enum-util";

enum MyEnum {
    FOO = 0,
    BAR = 1
}

function getMyEnum1(apiString: string): MyEnum {
    // throws informative error if "apiString" is not 
    // "FOO" or "BAR"
    return $enum(MyEnum).getValueOrThrow(apiString);
}

function getMyEnum2(apiString: string): MyEnum {
    // returns MyEnum.FOO if "apiString" is not 
    // "FOO" or "BAR"
    return $enum(MyEnum).getValueOrDefault(apiString, MyEnum.FOO);
}

function getMyEnum3(apiString: string): MyEnum | undefined {
    // returns undefined if "apiString" is not 
    // "FOO" or "BAR"
    return $enum(MyEnum).getValueOrDefault(apiString);
}

// type: ("FOO" | "BAR")
// value: "BAR"
const enumName = $enum(MyEnum).getKeyOrThrow(1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM