为了增强代码的可靠性,我使用以下函数将原始字符串转换为枚举值:
export function getSafelyEnumValue<T>(value: string | undefined, enumClass: { [s: string]: string }): T {
if (value === undefined) {
throw new NullPointerException()
}
if (!Object.values(enumClass).includes(value)) {
throw new UnknownEnumRawValueException(value)
}
return value as T
}
然后,当我想把一个字符串转换成枚举类型时:
const enumValue = getSafelyEnumValue<MyEnum>(rawString, MyEnum)
这比执行简单的强制转换要好:
const enumValue = rawString as MyEnum
因为如果rawString不属于MyEnum,而getSafelyEnumValue属于MyEnum,那么最后这段代码不会抛出任何异常。当我有这样的简单枚举时,这个函数工作得非常好:
export enum OrderSideDto {
SELL = "sell",
BUY = "buy",
}
有时候,我会向枚举添加方法,将它们来回转换为其他枚举类型。为此,我使用了众所周知的模式,即创建一个与枚举同名的名称空间,并将方法放入其中:
export namespace OrderSideDto {
export function toOrderSide(orderSideDto: OrderSideDto): OrderSideEntity {
switch(orderSideDto) {
case OrderSideDto.SELL: return OrderSideEntity.SHORT;
case OrderSideDto.BUY: return OrderSideEntity.LONG;
}
}
}
当我使用这个模式时,我的方法getSafelyEnumValue不再编译,我在TS中遇到了这个错误:
Argument of type 'typeof OrderSideDto' is not assignable to parameter of type '{ [s: string]: string; }'. Property 'toOrderSide' is incompatible with index signature. Type '(orderSideDto: OrderSideDto) => Side' is not assignable to type 'string'
关于如何使用方法使getSafelyEnumValue
与枚举兼容有什么想法吗?
1条答案
按热度按时间lf5gs5x21#
枚举转换为POJO,举个例子:
typescript 中的此枚举...
...在javascript中被转换为以下内容(请注意,基于数字的枚举有一个稍微不同的转换):
这个复杂的代码在执行时会产生以下结果(同样,基于数字的枚举也有点不同):
到目前为止一切顺利。现在,当你声明一个名称空间时,JS要么创建一个具有这个名称的对象,要么接受一个具有这个名称的现有对象。在你的例子中,后者发生了。无论哪种方式,声明的名称空间的内容都会被填充到请求的对象中。
这意味着,在您的例子中,对象填充了名称空间中声明的函数(不完全像我在这里描述的那样,但您明白了):
换句话说,您最终得到的对象具有枚举的属性和名称空间中的属性。
enumClass
是一个任何类型的对象,其属性严格地只由字符串组成:因此,您还需要接受一个可调用对象(即
Function
)。