title: What is the rationale behind the way generics expand in Typescript?
body: <p>I have recently been learning Typescript, I really like it just for the types.</p>
  
  <p>One thing I really like is these 'conditional types' which allow me to write things like</p>
  
  <pre><code>type W&lt;T&gt; = T extends Array&lt;infer R&gt; ? R : any;
  type Z = string[];
  type X = W&lt;Z&gt;; // string
  </code></pre>
  
  <p>Really useful.</p>
  
  <p>I have been writing my own 'utility' types to learn the typescript system better, a built in utility to Typescript is 'Extract' which takes from T the types which are assignable to U.</p>
  
  <pre><code>type Z = { a: "hi"; b: string } | { a: "bye"; b: number };
  type W = Extract&lt;Z, { a: "hi" }&gt;; // { a: "hi", b: string }
  </code></pre>
  
  <p>Really nice as well, I was trying to work out how to implement it myself and couldn't do so, eventually I found out that it is essentially </p>
  
  <pre><code>type MyExtract&lt;T, U&gt; = T extends U ? T : never;
  </code></pre>
  
  <p>Which I find a bit bizarre, one of the rules I expect in life is that equality is transitive, so, perhaps naively I would expect that </p>
  
  <pre><code>type Z = { a: "hi"; b: string } | { a: "bye"; b: number };
  type MyExtract&lt;T, U&gt; = T extends U ? T : never;
  type W = MyExtract&lt;Z, { a: "hi" }&gt;; // { a: "hi", b: string }
  type ShouldBeSameAsW = Z extends { a: "hi" } ? Z : never; // never
  </code></pre>
  
  <p>Here on the 4th line I have substituted the T and U from the third line into the second line, but it produces a different result.</p>
  
  <p>I came to understand that the way Typescript works is that the third line when it actually evaluates the right hand side,  looks at T, if it is a union type it applies the right handside to every element of the union, and takes the union of that, so that actually W is like </p>
  
  <pre><code>type ShouldBeSameAsW = { a: "hi"; b: string } extends { a: "hi" }
      ? { a: "hi"; b: string }
      : never | { a: "bye"; b: number } extends { b: "bye" }
      ? { a: "bye"; b: number }
      : never;
  </code></pre>
  
  <p>Which is fine, I guess, except that I don't understand the reasoning that means that it's sensible for it to work this way, I'm also reasonably confident that Typescript wouldn't go about making equality not transitive, so I don't understand how it isn't based on the above example.</p>
  
  <p>So my question is</p>
  
  <p>What is the rationale behind making type </p>
  
  <pre><code>MyExtract&lt;T, U&gt; = T extends U ? T : never; 
  </code></pre>
  
  <p>expand in this weird way, how does it not render '=' non transitive, and why is there not just some additional syntax which is more transparent for this splitting up of T into its parts?</p>