如何使用相同的键将字符串枚举转换为另一个枚举?
How to cast string enum to another enum with the same keys?
由这 2 个具有相同键的字符串枚举给出:
enum StatusEnum {
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
WARN = 'WARN',
DEBUG = 'DEBUG',
}
enum RawStatusEnum {
SUCCESS = 'Success',
ERROR = 'Error',
WARN = 'Warn',
DEBUG = 'Debug',
}
我想将枚举 RawStatusEnum
的值转换为枚举 StatusEnum
的值,即:
const rawEnumValue = RawStatusEnum.ERROR // RawStatusEnum
const normalEnumValue = cast(rawEnumValue) // StatusEnum
但我在打字方面遇到问题......我已经了解了打字稿中的反向映射 ,但反向映射仅适用于数字枚举。提前致谢。
如您所述,string enums
don't automatically get a reverse mapping,因此从值中获取键并不像查找那么简单。
但是,编写辅助函数来为字符串枚举生成反向映射是相当简单的。但是编译器无法验证它是否已正确实现,因此您需要 type assertion。例如:
const reverseStringEnum = <T extends Record<keyof T, string>>(e: T) =>
Object.fromEntries(Object.entries(e).map(([k, v]) => [v, k])) as
{ [K in keyof T as T[K]]: K };
它也使用 Object.entries()
and Object.fromEntries()
methods to split the enum object into key-value pairs and then put it back together with the keys and values swapped. The input object type is T
, and the output object type is {[K in keyof T as T[K]]: K}
, which uses key remapping 交换键和值类型。
让我们在 RawStatusEnum
上测试一下:
const RawStatusReverseEnum = reverseStringEnum(RawStatusEnum);
/* const RawStatusReverseEnum: {
readonly Success: "SUCCESS";
readonly Error: "ERROR";
readonly Warn: "WARN";
readonly Debug: "DEBUG";
} */
看起来不错。现在我们可以通过进行一对查找将 RawStatusEnum
“转换”为 StatusEnum
。我们在 RawStatusReverseEnum
中查找键,然后使用键查找 StatusEnum
中的值:
const castRawToNormal = <T extends RawStatusEnum>(t: T) =>
StatusEnum[RawStatusReverseEnum[t]];
让我们使用它:
const rawEnumValue = RawStatusEnum.ERROR // RawStatusEnum
const normalEnumValue = castRawToNormal(rawEnumValue);
// const normalEnumValue: StatusEnum.ERROR
console.log(normalEnumValue); // "ERROR"
看起来不错。编译器甚至知道 normalEnumValue
的类型是 StatusEnum.ERROR
.
由这 2 个具有相同键的字符串枚举给出:
enum StatusEnum {
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
WARN = 'WARN',
DEBUG = 'DEBUG',
}
enum RawStatusEnum {
SUCCESS = 'Success',
ERROR = 'Error',
WARN = 'Warn',
DEBUG = 'Debug',
}
我想将枚举 RawStatusEnum
的值转换为枚举 StatusEnum
的值,即:
const rawEnumValue = RawStatusEnum.ERROR // RawStatusEnum
const normalEnumValue = cast(rawEnumValue) // StatusEnum
但我在打字方面遇到问题......我已经了解了打字稿中的反向映射
如您所述,string enums
don't automatically get a reverse mapping,因此从值中获取键并不像查找那么简单。
但是,编写辅助函数来为字符串枚举生成反向映射是相当简单的。但是编译器无法验证它是否已正确实现,因此您需要 type assertion。例如:
const reverseStringEnum = <T extends Record<keyof T, string>>(e: T) =>
Object.fromEntries(Object.entries(e).map(([k, v]) => [v, k])) as
{ [K in keyof T as T[K]]: K };
它也使用 Object.entries()
and Object.fromEntries()
methods to split the enum object into key-value pairs and then put it back together with the keys and values swapped. The input object type is T
, and the output object type is {[K in keyof T as T[K]]: K}
, which uses key remapping 交换键和值类型。
让我们在 RawStatusEnum
上测试一下:
const RawStatusReverseEnum = reverseStringEnum(RawStatusEnum);
/* const RawStatusReverseEnum: {
readonly Success: "SUCCESS";
readonly Error: "ERROR";
readonly Warn: "WARN";
readonly Debug: "DEBUG";
} */
看起来不错。现在我们可以通过进行一对查找将 RawStatusEnum
“转换”为 StatusEnum
。我们在 RawStatusReverseEnum
中查找键,然后使用键查找 StatusEnum
中的值:
const castRawToNormal = <T extends RawStatusEnum>(t: T) =>
StatusEnum[RawStatusReverseEnum[t]];
让我们使用它:
const rawEnumValue = RawStatusEnum.ERROR // RawStatusEnum
const normalEnumValue = castRawToNormal(rawEnumValue);
// const normalEnumValue: StatusEnum.ERROR
console.log(normalEnumValue); // "ERROR"
看起来不错。编译器甚至知道 normalEnumValue
的类型是 StatusEnum.ERROR
.