typescript - 打字稿:如何遍历由枚举值索引的对象
问题描述
我有一个这样声明的对象:
type MyType = { [key in MyEnum]?: number}
MyEnum 具有这种形式:
enum MyEnum {
Foo = 1, Bar = 2
}
我想遍历我的对象键/值对,然后返回枚举值:
const myObject: MyType = {...}
for (const myKey in myObject) {
// myKey is of type string, not "MyEnum". How to get back to it?
}
有没有办法做到这一点?
解决方案
这个看似令人惊讶的问题是在 Typescript 中进行鸭式输入的结果,并且在较小程度上是对象在 Javascript 中的工作方式。
由于两个原因,将myKey
其键入为字符串。首先,Typescript 不能保证一个对象只包含MyType
. 鸭子类型允许您使用与请求MyType
的位置具有相同和更多属性的对象。MyType
这是 Typescript 的一个特性,但在这种情况下是一个障碍。
鸭子打字的例子
// Types
enum MyEnum {
Foo = 1, Bar = 2
};
type MyType = { [key in MyEnum]?: number}
// Duck typing example
const normalObject: MyType = { [MyEnum.Foo]: 3, [MyEnum.Bar]: 4 };
const duckTypedObject = { [MyEnum.Foo]: 5, "extraProperty": 10};
function myFunction(obj: MyType){
for (const myKey in obj) {
console.log(myKey);
}
}
myFunction(normalObject);
// This will print out "extraProperty" as well.
myFunction(duckTypedObject);
其次,因为 Javascript 中对象的属性只能是符号或字符串,所以其他类型被强制转换为字符串。由于 for 循环只会遍历对象的字符串属性,Typescript 选择string
最具体的类型 for myKey
。
通常你仍然可以通过在构造myKey
之外声明一个变量来输入。loop
在这种情况下不起作用,因为您使用的是数字枚举。您需要解析字符串才能再次获取数字并将其转换回枚举。我强烈建议不要这样做。但是,您可以使用字符串枚举,但如果您的同事使用鸭子类型,这仍然会使您面临错误。
字符串枚举解决方案
enum MyStringEnum {
Foo = "FOO", Bar = "BAR"
}
type MyType2 = { [key in MyStringEnum]?: number};
const obj: MyType2 = { [MyStringEnum.Foo]: 3};
let myKey: MyStringEnum;
for (const myKey in obj){
console.log(myKey);
}
我的建议是使用Map
Typescript 中的类型。正如您所看到的,在没有任何额外的黑客攻击的情况下键入了密钥,并且您回避了与鸭子键入有关的问题。
enum MyEnum {
Foo = 1, Bar = 2
};
let myMap = new Map<MyEnum, number>([
[MyEnum.Foo, 3],
[MyEnum.Bar, 4]
]);
for (const [key] of myMap){
console.log(key);
}
推荐阅读
- swiftui - swiftUI中的这个pdf缩略图预览有什么问题
- string - 如何在 Julia 中获取字符串的子字符串?
- python - 显示带有比例和填充的条形图不起作用
- python - 为什么我的 python 脚本运行正常,但在我尝试跟踪它时却没有?
- c++ - 引用的歧义
- reactjs - Formik 将表单重置为初始值
- solr - Apache Solr 与 Deno?
- node.js - 如何在 trc20 网络中获取多个账户余额
- angular - 如何在中使用 formControlName
- reactjs - 当存在重复记录并触发错误消息时,如何将验证方法添加到 Yup 模式中