title: Typescript. Correctly typing function parameter that depends on property in the same object literal
body: <p>I have types where one depends on another:</p>
  
  <pre class="lang-ts prettyprint-override"><code>type source = string | number;
  type derivative&lt;T extends source&gt; = T extends string ? string[] : number[];
  </code></pre>
  
  <p>I can use them in function arguments and get correct inference:</p>
  
  <p><a href="https://i.stack.imgur.com/YM1E8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YM1E8.png" alt="enter image description here"></a></p>
  
  <p>Now I want to use them in interface:</p>
  
  <pre><code>interface Test&lt;T extends source&gt; {
      src: T;
      handler: (dvr: derivative&lt;T&gt;) =&gt; void;
  }
  </code></pre>
  
  <p>Again I can use it as function input and get right types:</p>
  
  <p><a href="https://i.stack.imgur.com/gxZUy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gxZUy.png" alt="enter image description here"></a></p>
  
  <p>But if I need to pass several tasks, typescript can't infer right type:</p>
  
  <p><a href="https://i.stack.imgur.com/nUSDp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/nUSDp.png" alt="enter image description here"></a></p>
  
  <p>Is it possible to fix this? Presumably by changing <code>handleTestArr</code> function definition.</p>
  
  <p><a href="http://www.typescriptlang.org/play/index.html#src=type%20source%20%3D%20string%20%7C%20number%3B%0D%0Atype%20derivative%3CT%20extends%20source%3E%20%3D%20T%20extends%20string%20%3F%20string%5B%5D%20%3A%20number%5B%5D%3B%0D%0A%0D%0A%0D%0A%0D%0Afunction%20handle%3CT%20extends%20source%3E(src%3A%20T%2C%20handler%3A%20(dvr%3A%20derivative%3CT%3E)%20%3D%3E%20void)%20%7B%0D%0A%7D%0D%0Ahandle(&#39;&#39;%2C%20x%20%3D%3E%20%7B%7D)%0D%0Ahandle(1%2C%20x%20%3D%3E%20%7B%7D)%0D%0A%0D%0A%0D%0A%0D%0Ainterface%20Test%3CT%20extends%20source%3E%20%7B%0D%0A%20%20%20%20src%3A%20T%3B%0D%0A%20%20%20%20handler%3A%20(dvr%3A%20derivative%3CT%3E)%20%3D%3E%20void%3B%0D%0A%7D%0D%0A%0D%0A%0D%0A%0D%0Afunction%20handleTest%3CT%20extends%20source%3E(t%3A%20Test%3CT%3E)%20%7B%0D%0A%7D%0D%0AhandleTest(%7B%0D%0A%20%20%20%20src%3A%201%2C%0D%0A%20%20%20%20handler%3A%20x%20%3D%3E%20%7B%7D%2C%0D%0A%7D)%0D%0A%0D%0A%0D%0A%0D%0Afunction%20handleTestArr(ts%3A%20Test%3Csource%3E%5B%5D)%20%7B%0D%0A%7D%0D%0AhandleTestArr(%5B%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20src%3A%201%2C%0D%0A%20%20%20%20%20%20%20%20handler%3A%20x%20%3D%3E%20%7B%7D%2C%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20src%3A%20&#39;&#39;%2C%0D%0A%20%20%20%20%20%20%20%20handler%3A%20x%20%3D%3E%20%7B%7D%2C%0D%0A%20%20%20%20%7D%2C%0D%0A%5D)" rel="nofollow noreferrer">Playground</a></p>