对枚举使用计算值

Joã*_*ulo 5 enums typescript

我有以下情况:

enum T {
    A = "a"
};

enum U {
    [T.A] = "u"
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

枚举中不允许​​使用计算属性名称。

有办法解决吗?或者也许使用类似的资源可以让我有类似的行为?

Tad*_*sen 4

一种选择虽然不一定理想,但却是使用枚举中的显式值T,然后使用虚拟类型定义进行一些编译时断言:

enum T {
    A = "a"
};

enum U {
    // T.A
    a = "u"
}
/** this raises a compile error if not all values of enum T are valid keys of the enum U */
type _ensure_keyof_U_equals_T = typeof U[T];
Run Code Online (Sandbox Code Playgroud)

请注意,您实际上不会_ensure_keyof_U_equals_T在代码中的其他任何地方使用它,它只是在枚举与您想要的形状不匹配时抛出类型错误。(例如游乐场)如果 T 包含 U 中不存在的元素,则会给出错误,指出“typeof U 没有属性 ___”,因此您必须确保 T 包含该属性才能编译代码。有点迂回但确实有效。

这是为了确保类型的值可以用作运行时创建的对象的T动态键。U请注意,枚举的优点之一是,const使用这种架构无法选择创建它们。

另一种方法是创建U一个对象定义而不是像这样的枚举:

type U = (typeof U)[keyof typeof U]
const U = {
    [T.A]: "u"
} as const
Run Code Online (Sandbox Code Playgroud)

这并不断言 的每个可能的元素T都是有效的键(尽管_ensure_keyof_U_equals_T上面的元素在这里仍然完全相同),但确实创建了一个与枚举情况几乎无法区分的对象/类型组合,唯一的区别是检查对于字符串文字来说不太严格:

enum A {
    a = "b"
}
type B = (typeof B)[keyof typeof B];
const B = {
    element: "b"
} as const

function should_only_accept_enum_A(item: A){}
function should_only_accept_enum_B(item: B){}

should_only_accept_enum_A("b") // fails
should_only_accept_enum_B("b") // succeeds
Run Code Online (Sandbox Code Playgroud)

但是,如果您想将非字符串值放入该结构中,这感觉就像您会这样做的情况,无论如何它确实允许这样做。