typescript 如果我忘记给Map添加枚举值,编译器能警告我吗?

eufgjt7s  于 2023-03-04  发布在  TypeScript
关注(0)|答案(1)|浏览(170)

假设我有一个类似的情况:

enum E {
    Foo,
    Bar
}

const map = new Map<E, string>(
    [
        [E.Foo, "some data"],
        [E.Bar, "some other data"]
    ]
);

在map中包含E的所有值是很重要的,这在编译时能保证吗?换句话说,如果一个新的值被添加到E中,编译器应该对我大喊:“嘿,你忘了把它也加到Map上了!"。
动机:E是从后端的一个类型通过一个构建步骤生成的。当后端发生变化时(例如,添加一个新的枚举值),我们希望在前端尽可能早地知道。

kx7yvsdv

kx7yvsdv1#

就像@nullptr建议的那样,您应该 * 可能 * 考虑使用Record:

const record: Record<E, string> = {
    [E.Foo]: "some data",
    [E.Bar]: "some other data",
};

如果你复制了一个键,丢失了一个键,或者有一个无关的键,那么这个方法就会出错。但是,如果你不能使用普通对象,而必须使用Map,那么我建议你:

const entries = [
    [E.Foo, "some data"],
    [E.Bar, "some other data"]
] as const;

type ExhaustiveCheck<T extends never = Exclude<E, typeof entries[number][0]>> = T;

const map = new Map<E, string>(entries);

我们可以假设Exclude在给定两个相同类型的项时返回never,这意味着如果我们的项是穷举的,排除E中的项将得到never,如果忘记了密钥,穷举检查将提供错误(不是最有用的,但它应该是足够的信息来推断为什么会发生)。如果你有一个额外的键,你会得到一个错误,当你试图创建Map。所以它有点像使用一个记录...然而,它不能防止重复密钥。
Playground

相关问题