简体   繁体   English

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

[英]Typescript - How to properly merge two enums that contain overlaps?

Given the following enums:给定以下枚举:

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

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

What is the proper way of merging them?合并它们的正确方法是什么? Note that they contain overlap in the key C = 'C' , so just MyFirstEnum | MySecondEnum请注意,它们在键C = 'C'中包含重叠,所以只是MyFirstEnum | MySecondEnum MyFirstEnum | MySecondEnum may cause some trouble, for example: 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>>'

If I understood correctly from this question How to merge two enums in TypeScript , Typescript does not handle different enums with duplicate keys and values well.如果我从这个问题How to merge two enums in TypeScript 中理解正确, Typescript 不能很好地处理具有重复键和值的不同枚举。

But if one really needs to merge enums with this overlap, how to do it with no (or less) further problems?但是,如果真的需要将枚举与这种重叠合并,如何在没有(或更少)进一步问题的情况下做到这一点?

Is that would work?那行得通吗?

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} 

equivalent to:相当于:

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

Needed to be call with keyof:需要用 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"}" 

But I would personally prefer this option:但我个人更喜欢这个选项:

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"}" 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM