【发布时间】:2021-02-09 22:58:03
【问题描述】:
我正在尝试编写一个通用函数来合并多个枚举。希望这个函数能完成以下相同的功能:
enum Mammals {
Humans = 'Humans',
Bats = 'Bats',
Dolphins = 'Dolphins',
}
enum Reptiles {
Snakes = 'Snakes',
Alligators = 'Alligators',
Lizards = 'Lizards',
}
const Animals = {
...Mammals,
...Reptiles,
}
type Animals = Mammals | Reptiles;
第一次尝试:
export const mergeEnums = <T extends any[]>(...enums: T): T[number] => {
return {
...enums,
};
};
// Results in Animals: typeof Mammals | typeof Reptiles
const Animals = mergeEnums(Mammals, Reptiles);
不幸的是,联合类型不太正确。 TypeScript 不允许访问密钥。示例类型错误:Property 'Snakes' does not exist on type 'typeof Mammals | typeof Reptiles'.
第二次尝试:
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I,
) => void
? I
: never;
export const mergeEnums = <T extends any[]>(
...enums: T
): UnionToIntersection<T[number]> => {
return {
...enums,
} as UnionToIntersection<T[number]>;
};
// Results in Animals: typeof Mammals & typeof Reptiles
const Animals = mergeEnums(Mammals, Reptiles);
这确实允许密钥访问,但是当同一个密钥存在于多个枚举中时,返回类型为never,这在我的使用中是一种可能性。
是否有可能实现与Animals: Mammals | Reptiles功能相同的解决方案?
【问题讨论】:
-
“当同一个键存在于多个枚举中时,这在我的使用中是一种可能性”似乎是一个奇怪的边缘情况;你为什么要这样做或允许这样做?无论如何,除了可变参数输入,它看起来像this question。我很乐意写一个新的答案,它使用递归对一组输入进行处理,但我并不认为它比
UnionToIntersection有很大的改进,除非你能清楚地说明你为什么想成为允许枚举键以这种方式发生冲突。 -
我同意 jcalz。当相同的键出现在两个枚举中时,您会会发生什么?它的值不能同时是第一个枚举和另一个枚举的值,因为两个不相同的原语没有重叠。
never是在这种情况下唯一有意义的类型。 -
呃,我还是写了一个答案????
-
????我正在将来自各种金融交易所的受支持资产代码合并到一个全球代码列表中,作为我实际使用的一部分。
标签: javascript typescript enums typescript4.0