【问题标题】:How can I use type key as enum?如何使用类型键作为枚举?
【发布时间】:2021-12-09 23:59:26
【问题描述】:

我有

type typeA = "A1" | "A2" | "A3";

那我要使用类型值方向

typeA.A1; // "A1"

有可能吗?

【问题讨论】:

  • 我很困惑。你不能使用enum,还是我错过了什么?
  • 好吧,这可能行得通,因为已经有一个类型,并且它由第 3 方维护。
  • 你不需要typeA.A1。只需使用"A1"。这是一个字符串字面量类型,不需要对值使用间接——使用字面量是类型安全的。
  • @IngoBürk 是正确的。联合类型(例如typeA)的全部意义在于限制您可以分配给具有该类型的变量的值。 typeA 不代表命名空间。事实上,由于type erasuretypeA 甚至不会存在于生成的 Javascript 中,因此在运行时也不存在!但我会写一个替代方案以防你可以说服第三方采用它。

标签: typescript type-erasure


【解决方案1】:

正如我在评论中所说,由于type erasure,您不能将类型别名用作枚举。 typeA 不会存在于生成的 Javascript 中,因此不会在运行时存在。[1]

由于您在评论中说typeA“由第 3 方维护”,因此您无能为力。但也有您无需做任何事情:

  • 既然可以写"A1",为什么还要在代码中写typeA.A1?这几乎就像在代码中定义 const TWO = 2 并使用 TWO 而不是文字 2
  • 使用typeA.A 代替"A1" 没有额外的类型安全性。静态类型检查将阻止您将除 typeA 允许的值之外的任何值分配/传递给具有该类型的任何变量或参数。
  • 任何支持 Typescript 的 IDE 都会自动建议此类变量和参数的合法值。

但是假设你真的需要/想要能够说typeA.A1...

代码必须以相反的方式工作:定义 Enum 值(不一定使用 enum 语法),然后定义表示这些值联合的类型别名。

例如:

enum A {A1 = "A1", A2 = "A2", A3 = "A3" }

// type typeA = "A1" | "A2" | "A3"
type typeA = keyof typeof A

用法:

function checkA(arg: typeA):void {
    console.log(arg)
}

checkA(A.A1)  //ok
checkA("A1")  //ok
checkA("A4")  //error

let v1: A = A.A1
let v2: typeA = "A1"
let v3: string = "A1"

checkA(v1)    //ok
checkA(v2)    //ok
checkA(v3)    //error

您可以改为将函数 arg 定义为 arg: A,但它会更加严格,只接受对 A 枚举的引用,而不是字符串 "A1" 或变量 v2

function checkA(arg: A):void {
    console.log(arg)
}

您必须说服第三方进行此更改。


[1] 有a nice table in the Typescript docs总结了转译成Javascript后存在哪些东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 2022-01-15
    • 2019-03-13
    • 1970-01-01
    • 2013-09-21
    • 2018-01-09
    • 1970-01-01
    相关资源
    最近更新 更多