繁体   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