TypeScript 枚举类型转换/强制类型转换

7
这个语句失败了。我该如何将一个枚举转换成另一个(它们是相同的)?
enum Enum1 {
  Key1 = 'key'
}

enum Enum2 {
  Key1 = 'key'
}

const key = Enum1.Key1
const key2 = key as Enum2

1
你可以描述一个实际的场景,说明在这种情况下你需要进行这项操作吗?这将有助于我们更好地理解问题。 - Akshar Patel
1
有时我会在多个地方定义相同的枚举,由于依赖边界的限制,无法从一个地方导入到另一个地方。因此,我认为保持它们完全相同会让TS编译器满意,但显然并非如此。 - Tony
5个回答

4
这里有一个适用于数字值的解决方案。但需要注意的是,此方法“危险”,因为没有确认或验证转换是否发生,所以可能无法满足您对编译时检查的要求。底线是,在将其转换为第二个枚举之前,您必须将其强制转换为一些中间兼容类型(数字、字符串、任何、未知),通过这样做,您已经脱离了任何有意义的语义检查。每当进行强制转换时,都意味着您放弃了编译时检查。
enum SeverityLevel {
    Verbose = 0,
    Warning = 1
}

enum InternalSeverity {
    Verbose = 0,
    Warning = 1
}


function CallMe(severity: SeverityLevel) {
    console.log(`SeverityLevel: ${severity}`);
}

function Convert(severity: InternalSeverity) {
    console.log(severity);
    console.log(SeverityLevel[severity]);
    console.log(InternalSeverity[severity]);

    CallMe(severity as number as SeverityLevel);
}

Convert(InternalSeverity.Warning);

输出

编写一个详细的转换函数可能会更好,该函数显式地映射值并可以检查例如警告在两个枚举中是否相同,如下所示:

switch (severity) {
   case SeverityLevel.Warning:
      return InternalSeverity.Warning;
      break;

这允许在枚举之间进行转换,对底层值的更改具有弹性(假设枚举的目的是使用名称来表示值,并且值本身并不重要),并满足编译时检查(只要某人从枚举中删除键,它就会出问题)。如果值比名称更重要,则可能需要稍微不同的方法。


1

您可以先将其转换为字符串,然后再转换为所需的枚举:

const key2 = key as string as Enum2

1
请不要仅仅发布代码作为答案,还要包括对代码的解释以及它是如何解决问题的。带有解释的答案通常质量更高,更有可能吸引赞同。 - Krzysztof Janiszewski
虽然这可能回答了问题,但它被标记为需要审核。没有解释的答案通常被认为是低质量的。请提供一些评论,说明为什么这是正确的答案。 - Dan

1
如果您使用数字而不是字符串作为枚举值,则可以这样操作:
enum Enum1 {
  Key1 = 2
}

enum Enum2 {
  Key1 = 2
}

const key = Enum1.Key1
const key2 = Enum2[Enum1[key]];

实际上,如果枚举键和值相同,则此方法也适用于字符串值:https://www.typescriptlang.org/play?#code/KYOwrgtgBAouEEYoG8CwAoKUDSwCeSAvFAOS4EkA0GW5ATFMWfnVRgL4YaiSzwNpMOfEVLkEbIfUZiWkzugwBjAPYgAzgBcoAa3wAuPpFEBZAIaaAFgDoATmZAATFRAAUASigA+KAAZrAKxQAPxGiNbiUIZwxhEsANzKalq6LNH8MjEQdADaengAuvFAA - Leksat

0

看起来Typescript确实不会检查可能的值,因此它没有注意到这些枚举是兼容的。 我现在正在做的是

const key2 = key as Enum1 & Enum2

这并不完美,因为它不能强制执行枚举的兼容性。 但仍然比扩展到 stringany 更好。


-1
在运行时,变量将包含枚举值(在您的情况下为key),因此您只需通过any进行强制转换即可。
const key = Enum1.Key1
const key2: Enum2 = key as any

2
我知道这在运行时可以工作。我希望找到一种编译时安全的方法来做到这一点。(例如,如果Enum2 def更改了,它应该会报错) - Tony
1
@Tony,我认为使用枚举无法实现这一点...也许如果你不使用枚举...我尝试了一些模拟枚举的类型,但允许在存在相同值的情况下在枚举之间进行赋值,使用字符串字面量。 - Titian Cernicova-Dragomir
是的,似乎这是解决方法 - 使用字符串联合而不是枚举。 - Tony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接