title: Typescript generic interface where property name and type are "T"
body: <p>I have a use-case where an external query returns an object with a property with the same name as one of my interfaces.  As you can see in the sample <code>executeQuery</code> function, if I pass in "message" as a query, then I will be returned an object with 1 property named "Message".</p>
  
  <p>I want to be able to create a generic interface of <code>T</code> that has 1 property where the name is the name of <code>T</code> and the type is <code>T</code>.</p>
  
  <p>I understand there are run-time solutions to this, but I was wondering if this was possible using only Typescript types at compile time.</p>
  
  <p>shared code:</p>
  
  <pre><code>function executeQuery&lt;T&gt;(query: "message" | "mailbox") {
      const data = query === "message" ?
          { Message: { id: 1 } } as unknown as T :
          { Mailbox: { id: 2 } } as unknown as T
      return { data: data }
  }
  
  interface Message {
      id: number
  }
  
  interface Mailbox {
      id: number
  }
  </code></pre>
  
  <p>1st solution:</p>
  
  <pre><code>interface AllContainer {
      Message: Message
      Mailbox: Mailbox
  }
  
  const messageQueryResult = executeQuery&lt;AllContainer&gt;("message")
  console.log(messageQueryResult.data.Message.id)
  
  const mailboxQueryResult = executeQuery&lt;AllContainer&gt;("mailbox")
  console.log(mailboxQueryResult.data.Mailbox.id)
  </code></pre>
  
  <p>2nd solution:</p>
  
  <pre><code>interface MessageContainer {
      Message: Message
  }
  
  interface MailboxContainer {
      Mailbox: Mailbox
  }
  
  const messageQueryResult2 = executeQuery&lt;MessageContainer&gt;("message")
  console.log(messageQueryResult2.data.Message.id)
  
  const mailboxQueryResult2 = executeQuery&lt;MailboxContainer&gt;("mailbox")
  console.log(mailboxQueryResult2.data.Mailbox.id)
  </code></pre>
  
  <p>What I want to be able to do:</p>
  
  <pre><code>interface GenericContainer&lt;T&gt; {
      [T.Name]: T  // invalid Typescript
  }
  
  const messageQueryResult3 = executeQuery&lt;GenericContainer&lt;Message&gt;&gt;("message")
  console.log(messageQueryResult3.data.Message.id)
  
  const mailboxQueryResult3 = executeQuery&lt;GenericContainer&lt;Mailbox&gt;&gt;("mailbox")
  console.log(mailboxQueryResult3.data.Mailbox.id)
  </code></pre>