title: How does Flow interpret generic types?
body: <p>I would like to learn how Flow decides what type to use for a generic type, and if there is a way to control at what level the generic type gets inferred (what I mean by this is explained further down).</p>
  
  <blockquote>
    <p>This question is inspired by <a href="https://stackoverflow.com/questions/54873504/how-to-type-a-generic-function-that-returns-subtype">How to type a generic function that returns subtypes</a>. I think there is a distinction between the two questions because this one focuses on understanding how <code>T</code> is chosen, where as the linked on is focuses on typing the return type of a function.</p>
  </blockquote>
  
  <p>The identity function is a great example to dissect. Its type is fairly straightforward</p>
  
  <pre><code>function identity&lt;T&gt;(value: T): T;
  </code></pre>
  
  <p>This seems like enough information to know what the implementation should be. However, I feel like this type is insufficient to know what the identity function actually does. For example, we could have (as the linked question tries to do),</p>
  
  <pre><code>function identity&lt;T&gt;(value: T): T {
    if (typeof value === 'string') {
      return '';
    }
  
    return value;
  }
  </code></pre>
  
  <p><a href="https://flow.org/try/#0GYVwdgxgLglg9mABDAJgUzLKBPAPAFQD4AKANwEMAbENALkXwEp79EBvAKEWWEWJwAOaOLwrU0iALzTEAcgDOUAE4wwAc1mN2XboiVooIJUlmyA3DoC+HHfsPHEYmhctA" rel="nofollow noreferrer">Try Flow</a></p>
  
  <p>This does not typecheck, with Flow complaining about returning the empty string. However, I would imagine in many languages that this would be fine--we are returning a <code>string</code> when a <code>string</code> was inputted, otherwise we are returning the original <code>value</code> of type <code>T</code>--but for some reason Flow does not like this.</p>
  
  <p>My confusion is compounded by both <a href="https://stackoverflow.com/a/54877967/11308639">this answer</a>, where we can return <code>value.substr(0, 0)</code> instead of the empty string and Flow will no longer complain, and by the inability to return a strictly equal value,</p>
  
  <pre><code>function identity&lt;T&gt;(value: T): T {
    if (value === '') {
      return '';
    }
  
    return value;
  }
  </code></pre>
  
  <p><a href="https://flow.org/try/#0GYVwdgxgLglg9mABDAJgUzLKBPAPAFQD4AKANwEMAbENALkXwEp79EBvAKEWWETKpqIAvCMQByMY3ZduiAE5ooIOUgkBuGQF8OMhUpWIK1NBs1A" rel="nofollow noreferrer">Try Flow</a></p>
  
  <p>I think a major reason for this discrepancy is that literals can act like types in Flow, in addition to the "JavaScript type". For example,</p>
  
  <pre><code>const x: 5 = 5; // literal type
  const x: number = 5; // JavaScript type
  </code></pre>
  
  <p>are both valid. However, this means that when we have a function of type <code>T =&gt; T</code>, we do not know if Flow is inferring the literal or JavaScript type as the type.</p>
  
  <p>I would like to know if there is some way of either knowing what Flow infers for generic types in a function or if there is a way to scope the generic type to be at the "literal" level or "JavaScript" level. With this ability, we could type function that coerces values to the default value for that type (i.e., strings would go to the empty string, numbers would go to 0). Here the type of the function would effectively be <code>T =&gt; T</code>, but hopefully Flow could be prevented from complaining about returning the default values.</p>