使用枚举类型而不是字符串类型遍历 TypeScript 中的字符串枚举

3

我在 TypeScript 中有一个字符串枚举,我想像下面这样遍历它。然而,当我这样做时,迭代器的类型是字符串而不是枚举类型。

enum Enum { A = 'a', B = 'b' };

let cipher: { [key in Enum]: string };

for (const letter in Enum) {
    cipher[letter] = 'test'; // error: letter is of type 'string' but needs to be 'Enum'
}

我收到的确切错误信息是这个:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: string; b: string; }'.
  No index signature with a parameter of type 'string' was found on type '{ a: string; b: string; }'.ts(7053)

这看起来很奇怪,因为保证该信是一个枚举。有没有什么方法可以解决这个问题?


2
我认为我的解释并不完美,所以我将其作为评论发布。 cipher 将具有 Enum 值作为密钥,即 { a: string, b: string },因为您正在使用字符串枚举,但是当您使用 for ... in 进行迭代时,您正在迭代生成的对象的可枚举属性,即 ['A', 'B'],因为该对象被生成为 var Enum; (function (Enum) { Enum["A"] = "a"; Enum["B"] = "b"; })(Enum || (Enum = {})); - robertgr991
1
一个解决方法是使用 for ... ofObject.values 迭代对象的值,因为枚举本身不可迭代。 最终代码:for (const letter of Object.values(Enum)) { cipher[letter] = 'test'; // 错误:letter 的类型为 'string',但需要 'Enum' } - robertgr991
@robertgr991,非常好,谢谢! - Oliver
1个回答

3

我将把自己的评论发布为答案,这样问题就不会无解了。

cipher 的类型将以 Enum 的值作为密钥,即:

let cipher: {
  a: string;
  b: string;
}

因为您正在使用字符串枚举。但是,当使用for...in循环迭代时,您会遍历生成的对象的可枚举属性,这些属性是['A', 'B'],因为生成的对象(TypeScript v4)将是:
var Enum;
(function (Enum) {
    Enum["A"] = "a";
    Enum["B"] = "b";
})(Enum || (Enum = {}));

所以你需要遍历枚举值。 为此,您可以使用 Object.values 来获取其值的数组和 for...of 来进行迭代。这样,letter 类型将是 Enum

for (const letter of Object.values(Enum)) {
    cipher[letter] = 'test'; // error: letter is of type 'string' but needs to be 'Enum'
}

我以前从未在枚举中使用过for...in,但我本来期望编译器有足够的信息,使得for...inletter严格类型化为"A" | "B"的联合类型,但似乎它将类型扩大为string


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