title: Conditional type based on value of variable in a class (TypeScript)
body: <p>I'm creating a generic class named <code>Loadable&lt;T&gt;</code>, with two fields. One is named <code>state</code>, and contains the current state of the loadable resource. The second is named <code>data</code>, and contains the value of the loadable resource. </p>
  
  <p><code>state</code> is defined as <code>"loading" | "loaded" | "error"</code>, and I'd like to type of <code>data</code> to change based on the current value of <code>state</code>.</p>
  
  <p>For example, if <code>state</code> is <code>"loading"</code>, then <code>data</code> should be <code>null</code>. I cannot figure out the syntax to do this.</p>
  
  <p>I've created a <code>type</code> named <code>LoadableState&lt;T, U&gt;</code> which is defined as:</p>
  
  <pre><code>    type LoadableState&lt;T, U&gt; =
          T extends "loaded" ? U :
          T extends "loading" ? null :
          T extends "error" ? string :
          never;
  </code></pre>
  
  <p>Where <code>T</code> passed must be the type <code>"loaded" | "loading" | "error"</code>.</p>
  
  <p>This part works, but trying to define <code>data</code> from this does not.</p>
  
  <pre><code>export class Loadable&lt;T&gt; {
      public state: "loaded" | "loading" | "error" = "loading";
  
      public data: LoadableState&lt;state, T&gt;;
      //                         ^^^^^ Cannot find name 'state`
  }
  </code></pre>
  
  <p>TypeScript throws the following error: <code>Cannot find name 'state'</code></p>
  
  <hr>
  
  <p>Other things I've tried:</p>
  
  <pre><code>public data: LoadableState&lt;this.state, T&gt;;
  // Duplicate identified 'state'
  
  public data: LoadableState&lt;typeof this.state, T&gt;;
  // Cannot find name 'this'
  
  public data: LoadableState&lt;typeof state, T&gt;;
  // Cannot find name 'state'
  
  public data: state extends "loaded" ? T :
      state extends "loading" ? null :
      state extends "error" ? string :
      never;
  // Cannot find name 'state'
  </code></pre>
  
  <hr>
  
  <p>I'm not sure if this is actual possible. If this isn't, is there another solution to this problem?</p>