typescript - 在 for in 循环中丢失枚举类型信息
问题描述
在下面的示例中,键的myColors
类型为Color
。但是,我在遍历myColor
对象时无法保留该信息。
enum Color {
Red = 'RED',
Green = 'GREEN',
}
type MyColors = {
[C in Color]?: string;
}
const myColors: MyColors = {
[Color.Red]: '#8B0000',
}
for (const [name, hex] of Object.entries(myColors)) {
// name is of type string here instead of Color
}
使用常规for in
循环,或者Object.keys(myColors)
也将枚举键转换为字符串。
循环遍历对象的属性时,有什么方法可以保留键的类型?如果不是,我怎么能断言name
在我的循环中是 type Color
?
解决方案
TypeScript 的 for 定义Object.entries
被重载,但两个重载都明确地使用字符串作为键类型。来自lib/lib.es2017.object.d.ts
:
/** * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][]; /** * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ entries(o: {}): [string, any][];
我确信这是有充分理由的。:-) 但是您可以定义自己的entries
不使用string
:
// Our `entries` function
function entries<T>(o: T): [keyof T, T[keyof T]][] {
return Object.entries(o) as unknown as [keyof T, T[keyof T]][];
}
然后它工作:
for (const [name, hex] of entries(myColors)) {
// type of `name` is `Color` now
}
更进一步,我发现如果我添加以下声明:
interface ObjectConstructor {
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: T): [keyof T, T[keyof T]][];
}
这样,您的原始代码就可以按预期工作:
for (const [name, hex] of Object.entries(myColors)) {
// type of `name` is `Color` now
}
(我用真正的编译器仔细检查了这一点,而不仅仅是操场,通过const n: Color = name;
在循环体中。TypeScript 抱怨它没有声明,但有声明它很高兴。)
但是,TypeScript 问题列表中的一些问题让我认为定义可能会对您传递的其他类型的事情造成麻烦Object.entries
,特别是这个和这个评论。因此,您可能希望拥有单独的功能(这很可能会使 JIT 消失)并在相关的地方使用它。
推荐阅读
- javascript - Google Recaptcha V3 - 通过 URL 加载验证码时的小部件 ID
- amazon-dynamodb - 如何在我的 Amplify 架构中创建二级索引?
- c# - 无法使用 C# HttpClient 获取任何 cookie
- mysql - 如何在 1 个 SQL 请求中组合 2 个表?
- python - 在 seaborn 线图中设置倾覆
- java - 自动编写 JPA 存储库类时出现空指针异常
- python - 在 matplotlib 3D 图中合并网格线和轴
- javascript - 如何在 Internet Explorer 11 中获得元素脚本的垂直反向顺序
- html - 如何解决轮播的图像路径问题
- mysql - Express 重定向错误:使用 NodeJS 和 MySQL 发送后无法设置标头