[英]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-util
( github , npm ),您可以通过运行时验证在枚举值和名称(沿任一方向)之间执行类型安全的转换。 如果在运行时遇到无效值,则可以选择引发错误或返回默认值(默认情况下未定义)的方法变体。
例:
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.