0

So here's a simplified testcase of what I'm fighting:

const testCase = {a:{b:"result"}}

for (const i in testCase) {
    console.log("i", i)
    for (const j in testCase[i]){
        console.log("j", j)
    }
}

This fails with:

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: { b: string; }; }'.
  No index signature with a parameter of type 'string' was found on type '{ a: { b: string; }; }'.

5     for (const j in testCase[i]){
                   

I can work around this by casting i as a keyof typeof testCase.

const testCase = {a:{b:"result"}}

for (const i in testCase) {
    let typedIndex = i as keyof typeof testCase
    console.log("i", i)
    for (const j in testCase[typedIndex]){
        console.log("j", j)
    }
}

However, this gets cumbersome depending on how many sub-ojbects I need to iterate through? Is there a better way to deal with this or am I just heading towards an anti-pattern of not having a predefined shape for testCase.

Gates
  • 13
  • 4

1 Answers1

0

I think I may have found an answer, unless I'm explicitly setting what the keys of testCase are, they are by definition any so by changing this to use an interface like this:

interface TestCase {
    [prop:string]: {
        [prop:string]: string
    }
}
const testCase:TestCase = {a:{b:"result"}}

When I run my for...in loop it will know the type of the key being returned.

Here's the completed version:

interface TestCase {
    [prop:string]: {
        [prop:string]: string
    }
}
const testCase:TestCase = {a:{b:"result"}}

for (const i in testCase) {
    console.log("i", i)
    for (const j in testCase[i]){
        console.log("j", j)
    }
}
Gates
  • 13
  • 4