title: Typescript Nested Tagged/Discriminated Union Types
body: <p>Let's say I have the following types (syntax is Elm-ish/Haskell-ish):</p>
  
  <pre><code>type Reply = LoginReply | LogoutReply
  type LoginReply = LoginSucceeded | AlreadyLoggedIn String
  </code></pre>
  
  <p>If I try to model it using Typescript's discriminated unions, I'll face the problem that <code>LoginReply</code> needs to have a property <code>kind</code> with value "loginReply" but it can't because it's declared using <code>type</code> keyword, not <code>class</code>.</p>
  
  <p>That's my best shot at the problem till now:</p>
  
  <pre><code>type Reply = LoginReply | LogoutReply
  
  type LoginReply = LoginSucceeded | AlreadyLoggedIn
  
  interface LoginSucceeded {
    kind: "loginSucceeded";
  }
  
  interface AlreadyLoggedIn {
    kind: "alreadyLoggedIn";
    loggedInUsername: string;
  }
  
  interface LogoutReply {
    kind: "logoutReply";
  }
  </code></pre>
  
  <p>As you can see, one can't even use <code>"loginReply"</code> anywhere and thus can't be used in discrimination.</p>
  
  <p>The only workaround I have for knowing a <code>Reply</code> variable is a <code>LoginReply</code> is to see if its <code>kind</code> is one of <code>"loginSucceeded"</code> and <code>"alreadyLoggedIn"</code>.</p>
  
  <p>So, how do I achieve what I want in Typescript? <strong>How to create a discriminated union type whose child types are discriminated-union types themselves?</strong></p>