typescript - how can i properly type the index signature on a nested for...in loop in typescript?
问题描述
I have a RootType
like this
Type1 = {
nestedProp1: string
nestedProp2: string
}
Type2 = {
nestedProp3: string
nestedProp4: boolean
}
type RootType = {
prop1?: Type1
prop2?: Type2
}
And i'm trying to iterate through it to get all of the values like this:
const root: RootType = {
prop1: {
nestedProp1: 'foo',
nestedProp2: 'bar'
},
prop2: {
nestedProp3: 'baz',
nestedProp4: false
}
}
for(const key in root) {
for(const nestedKey in root[key as keyof RootType]) {
console.log(root[key as keyof RootType][nestedKey]) <---- how do you get the index signature type for the nested type key?
}
{
For the top level, keyof RootType
works fine for the top level keys, but i can't seem to get the nested key type. I've tried root[key as keyof RootType][nestedKey as keyof Type1 | keyof Type2]
which dosen't work, i've tried creating a new interface that extends the RootType interface with a nested index signature as a string, but typescript complains that string
isn't compatible with "prop1" | "prop2"
I'd rather not modify the RootType as it is generated off of a graphql schema, and if i change it, it'll require a custom type definition in a config file that we'll have to maintain, so a local overload would be preferable, and the best possible solution would be a clean way of getting typescript to infer the key type in a for...in loop so it dosen't have to be casted at all.
解决方案
您可以使用const
在循环的每一级存储当前键值对的值for
,以便您可以访问keyof typeof <...>
声明中的值:
for (const key in root) {
const nestedObj = root[key as keyof typeof root];
for (const nestedKey in nestedObj) {
const nestedValue = nestedObj[nestedKey as keyof typeof nestedObj];
console.log(nestedValue);
}
}
请参阅 TypeScript Playround 上的概念验证。
或者,如果您更喜欢直接引用对象类型而不是对象本身的旧方法,这是可能的,但这也意味着您需要对所有嵌套对象键使用联合类型:
for (const key in root) {
const nestedObj = root[key as keyof RootType];
for (const nestedKey in nestedObj) {
// Can be very verbose, if your parent object has many nested object types
const nestedValue = nestedObj[nestedKey as keyof (Type1 | Type2)];
console.log(nestedValue);
}
}
推荐阅读
- python - 如何从 python 中的网络套接字解压缩 LZW 数据包?
- c# - 如何从 App.xaml.cs 导航到其他页面?
- entity - 有没有办法在 Draftjs 中添加牢不可破的实体?
- javascript - 为什么在循环中使用变量和直接调用索引有区别?
- django - 如何确定向特定听众群发送消息?
- c# - Microsoft.CodeAnalysis.FxCopAnalyzers 和 Microsoft.CodeAnalysis 之间有什么区别?
- firebase - Firebase 本机与 Ionic3 应用程序中的 Firebase JS 冲突(推送通知启用问题)
- r - 子集列表,将所有子集组合到一个大data.frame?
- c# - Expression Func 和 action 如何将值从 func 传递给 action
- c# - 在 DataGridView EditingControl 中捕获 EnterKey