title: Handling of optional properties of objects to be used as mapped or indexed properties
body: <p>I am working on a scenario of handling an <code>array</code> type property with <code>indexed</code> access. Tried to encapsulate the problem in simplest form here.</p>
  <pre><code>type User = {
      readonly name: string; 
      readonly roles: ReadonlyArray&lt;string&gt;;
  }
  
  const buildActions = &lt;T extends User&gt;(u: T) =&gt; {
      // Implementation
      return {login: (role: T['roles'][number]) =&gt; {
          console.log(u, role);
      }}
  }
  
  const actions = buildActions({name: 'user', roles: ['admin', 'client']} as const);
  actions.login('client');
  </code></pre>
  <p>So above code works fine. But in my scenario the property <code>roles</code> is optional.</p>
  <pre><code>type User = {
      readonly name: string; 
      readonly roles?: ReadonlyArray&lt;string&gt;;
  }
  </code></pre>
  <p>In above case we get error</p>
  <blockquote>
  <p>Type 'number' cannot be used to index type 'T[&quot;roles&quot;]'</p>
  </blockquote>
  <p>I tried to use conditional type to handle the scenario but didn't worked out.</p>
  <pre><code>const buildActions = &lt;T extends User&gt;(u: T) =&gt; {
      // Implementation
      return {login: (role: T['roles'] extends never ? never : T['roles'][number]) =&gt; {
          console.log(u, role);
      }}
  }
  </code></pre>
  <p>Definitely it's not the right way to handle such scenario, but covers the use case very well.</p>
  <p>Any idea how to get through this typing scenario?</p>
  <p>Thanks</p>