typescript 如何正确地合并两个包含重叠的枚举?

wqsoz72f  于 2023-02-05  发布在  TypeScript
关注(0)|答案(1)|浏览(146)

给定以下枚举:

enum MyFirstEnum {
  A = 'A',
  B = 'B',
  C = 'C'
}

enum MySecondEnum {
  C = 'C',
  D = 'D',
  E = 'E'
}

正确的合并方法是什么?注意它们在关键字C = 'C'中包含重叠,因此仅仅MyFirstEnum | MySecondEnum可能会引起一些麻烦,例如:

type BothEnums = MyFirstEnum | MySecondEnum

const myRecord: Partial<Record<BothEnums, string>> = {}
const someKey = MyFirstEnum.C

myRecord[someKey] = 'some value' // ❌ Property '[MyFirstEnum.C]' does not exist on type 'Partial<Record<BothEnums, string>>'

如果我对这个问题How to merge two enums in TypeScript的理解正确的话,Typescript不能很好地处理具有重复键和值的不同枚举。
但是,如果真的需要合并具有这种重叠的枚举,如何在没有(或更少)更多问题的情况下完成呢?

wh6knrhe

wh6knrhe1#

这样行吗?

type BothEnums = {[key in keyof typeof MyFirstEnum | keyof typeof MySecondEnum] : 
  key extends keyof typeof MyFirstEnum ? key extends keyof typeof MySecondEnum ? (typeof MySecondEnum[key]  | typeof MyFirstEnum[key]) :
    typeof MyFirstEnum[key] : key extends keyof typeof MySecondEnum ? typeof MySecondEnum[key] : never}

相当于:

type BothEnums = {
    A: MyFirstEnum.A;
    B: MyFirstEnum.B;
    C: MyFirstEnum.C | MySecondEnum.C;
    D: MySecondEnum.D;
    E: MySecondEnum.E;
}

需要使用keyof进行调用:

const myRecord: Partial<Record<keyof BothEnums, string>> = {}
const someKey1 = MyFirstEnum.C
const someKey2 = MySecondEnum.C

myRecord[someKey1] = 'some value 1' 
myRecord[someKey2] = 'some value 2' 

console.log(JSON.stringify(myRecord)) // "{"C":"some value 2"}"

但我个人更倾向于这个选择:

const MyFirstEnumDef = ['A','B','C'] as const satisfies readonly string[];
const MySecondEnumDef = ['C','D','E'] as const satisfies readonly string[];
type MyFirstEnum = typeof MyFirstEnumDef[number]
type MySecondEnum = typeof MySecondEnumDef[number]

type BothEnums = MyFirstEnum | MySecondEnum

const myRecord: Partial<Record<BothEnums, string>> = {}
const someKey1 = "C"
myRecord[someKey1] = 'some value 1' 

console.log(JSON.stringify(myRecord)) // "{"C":"some value 1"}"

相关问题