title: Get hash keys or type of value in a hash
body: <p>Coming from <code>flowtype</code>, I'm used to having things like <code>$Keys&lt;obj&gt;</code> to say 'the union of all the keys in <code>obj</code>'. Also, <code>$PropertyType&lt;obj, 'key'&gt;</code> to get the type of the value of <code>obj[key]</code>.</p>
  
  <p>I'm looking for something similar in Sorbet so I can make better use of generics.</p>
  
  <p>Ideally I want the <code>key</code> param to be <code>T.any(&lt;keys in the hash&gt;)</code> and the return value to be <code>typeof hash[:key]</code></p>
  
  <p>This is what I'd like to happen:</p>
  
  <pre class="lang-rb prettyprint-override"><code># my_rbi.rbi
  
  class SomeClass
  
    Elem = type_member
  
    sig { params(key: Keys[Elem]).returns(PropertyType&lt;Elem, key&gt;) }
    def [](key); end
  
  end
  
  # somewhere else
  
  sig { returns(SomeClass[{ my_key: String }]) } # add the hash as a generic
  def context
    # return the context
  end
  
  context[:my_key] # works, is a String!
  context[:not_my_key] # fails
  </code></pre>
  
  <p>Is any of this possible? what are my options here?</p>
  
  <p>Context:</p>
  
  <p>My use case is types for <code>graphql-ruby</code>, in particular <code>GraphQL::Query::Context</code>. It essentially delegates <code>[]</code> to an internal hash, which I know the shape of. I'd like to pass a generic to <code>GraphQL::Query::Context</code>, like <code>GraphQL::Query::Context[{ my_key: String }]</code>. Then, in the <code>def []</code> signature, I'd like to say what the available options for <code>key</code> are based on the generic hash.</p>