title: Avoid implicit 'any' type when using Object.keys in Typescript
body: <p>I have an Object with keys that I've typed and I want to loop over it and maintain their type, avoiding "Element implicitly has an 'any' type because 'ContactList' has no index signature".</p>
  
  <p>I know this has been discussed at length on Typescript's GitHub pages but I haven't found any solutions for what I'm trying to do here. Trying it both with enums and with unions, but I still get the error.</p>
  
  <p>Example with enums (<a href="https://www.typescriptlang.org/play/index.html#src=enum%20Names%20%7B%0D%0A%20%20Joe%2C%0D%0A%20%20Bill%2C%0D%0A%20%20Bob%0D%0A%7D%0D%0A%0D%0Atype%20ContactList%20%3D%20%7B%0D%0A%20%20%5Bkey%20in%20Names%5D%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20boolean%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20contactList%3A%20ContactList%20%3D%20%7B%0D%0A%20%20%5BNames.Joe%5D%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20true%2C%0D%0A%20%20%7D%2C%0D%0A%20%20%5BNames.Bill%5D%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20false%2C%0D%0A%20%20%7D%2C%0D%0A%20%20%5BNames.Bob%5D%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20true%2C%0D%0A%20%20%20%20%7D%2C%0D%0A%7D%3B%0D%0A%0D%0AObject.keys(contactList).forEach(name%20%3D%3E%20%7B%0D%0A%20%20%20%20console.log(contactList%5Bname%5D)%0D%0A%7D)%0D%0A%0D%0A" rel="noreferrer">playground</a>)</p>
  
  <pre><code>enum Names {
    Joe,
    Bill,
    Bob
  }
  
  type ContactList = {
    [key in Names]: {
      isFriend: boolean;
    }
  }
  
  const contactList: ContactList = {
    [Names.Joe]: {
      isFriend: true,
    },
    [Names.Bill]: {
      isFriend: false,
    },
    [Names.Bob]: {
      isFriend: true,
      },
  };
  
  Object.keys(contactList).forEach(name =&gt; {
      // turn on 'noImplicitAny' and get error
      console.log(contactList[name])
  })
  </code></pre>
  
  <p>Example with unions (<a href="https://www.typescriptlang.org/play/index.html#src=type%20Names%20%3D%20&#39;joe&#39;%20%7C%20&#39;bill&#39;%20%7C%20&#39;bob&#39;%0D%0A%0D%0Atype%20ContactList%20%3D%20%7B%0D%0A%20%20%5BK%20in%20Names%5D%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20boolean%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20contactList%3A%20ContactList%20%3D%20%7B%0D%0A%20%20joe%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20true%2C%0D%0A%20%20%7D%2C%0D%0A%20%20bill%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20false%2C%0D%0A%20%20%7D%2C%0D%0A%20%20bob%3A%20%7B%0D%0A%20%20%20%20isFriend%3A%20true%2C%0D%0A%20%20%20%20%7D%2C%0D%0A%7D%3B%0D%0A%0D%0AObject.keys(contactList).forEach(name%20%3D%3E%20%7B%0D%0A%20%20%20%20console.log(contactList%5Bname%5D)%0D%0A%7D)%0D%0A%0D%0A" rel="noreferrer">playground</a>)</p>
  
  <pre><code>type Names = 'joe' | 'bill' | 'bob'
  
  type ContactList = {
    [K in Names]: {
      isFriend: boolean;
    }
  }
  
  const contactList: ContactList = {
    joe: {
      isFriend: true,
    },
    bill: {
      isFriend: false,
    },
    bob: {
      isFriend: true,
      },
  };
  
  Object.keys(contactList).forEach(name =&gt; {
      // turn on 'noImplicitAny' and get error
      console.log(contactList[name])
  })
  </code></pre>
  
  <p>Either way, I'm telling typescript "the only keys allowed in this object are from Names" and as far as I understand index signatures, <code>[key in Names]</code> should be one, so I'm not sure why I'm seeing an error. Sorry if this is a noob question, I'm a little green with TS still. Thanks. </p>