TypeScript映射枚举

时间:2018-02-21 13:48:34

标签: typescript

在我的应用程序中,我们致力于混合模拟和真实的REST数据。在TypeScript中,我为了方便而定义了一大堆enumse。

当我使用数据创建任何类型的模拟数组时,我使用以下限制:

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在THIS question中建议我的方式

4 个答案:

答案 0 :(得分:2)

除了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')

尽管如此,这只是对原始答案的补充。

答案 1 :(得分:1)

您可以创建一个类似于对象的功能:

// 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

答案 2 :(得分:0)

如何使用enums代替枚举?

我猜你正在使用string literals来避免拼写错误,并且你希望TypeScript能够“抓住”它。因此,如果您使用export type Sex = 'male' | 'female'; var sex: Sex = 'mela'; // Typo => ERROR from typescript ,则类型安全,您将使用相同的“语言”与服务器通信

例如:

{{1}}

答案 3 :(得分:0)

使用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);