有没有办法在 Typescript 中转换枚举? 例如。我有一个原始枚举
enum original {
VALUE_1
VALUE_2
}
我想将大写转换为小写,如
enum original {
value_1
value_2
}
有可能吗?
答案 0 :(得分:1)
一般来说,你可以写一个名为lowercaseKeys()
的函数将任何对象的key转换为小写,然后assert这样的函数返回一个强类型的结果。返回类型涉及 key remapping 以创建映射类型,其中字符串 literal 通过 Lowercase
intrinsic string manipulation type 键转换为小写对应项:
function lowercaseKeys<T extends object>(obj: T): {
[K in keyof T as K extends string ? Lowercase<K> : K]: T[K]
} {
return Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k.toLowerCase(), v])
) as any;
}
同样,这应该适用于任何对象:
const example = lowercaseKeys({ STR: "hello", NUM: Math.PI });
/* const example: {
str: string;
num: number;
} */
console.log(example.num.toFixed(2)); // 3.14
您可以看到,在运行时,example
具有名为 str
和 num
的键,并且编译器知道这一点。
enum
也是一个具有键和值的对象,所以你可以用同样的方式转换它:
const LowercaseEnum = lowercaseKeys(OriginalEnum);
/* const LowercaseEnum: {
[x: number]: string;
readonly value_1: OriginalEnum.VALUE_1;
readonly value_2: OriginalEnum.VALUE_2;
} */
console.log(LowercaseEnum.value_1.toFixed()); // "0"
console.log(LowercaseEnum.value_2.toFixed()); // "1"
万岁!
嗯,就目前而言,这很棒。但请注意,enum
除了常规对象外还具有一些特殊功能。 (有关这种差异的更深入描述,请参见 this answer。)例如,enum
的名称也可以用作与它的价值:
interface Okay {
e: OriginalEnum;
}
但是 LowercaseEnum
只是一个对象,并没有声明为 enum
;没有名为 LowercaseEnum
的类型:
interface Oops {
e: LowercaseEnum; // error
// ~~~~~~~~~~~~~
// 'LowercaseEnum' refers to a value,
// but is being used as a type here.
}
如果你想要这样的类型,你必须做到:
type LowercaseEnum = OriginalEnum; // same values, so same type
另一个区别是像enum
这样的真数字OriginalEnum
有一个reverse mapping,如果OriginalEnum.VALUE_1
是0
,那么OriginalEnum[0]
是"VALUE_1"
:
console.log(OriginalEnum[0]); // "VALUE_1" as expected
但是转换后的版本没有有用的反向映射,因为只有它的键被改变了;它的价值不变:
console.log(LowercaseEnum[0]); // still "VALUE_1", unexpected?
因此,使用 LowercaseEnum
之类的内容时请小心:虽然有相似之处,但它不是真正的 enum
。