title: How to declare recursive types in typescript for method chaining?
body: <p>I want to make method chain class in typescript.
  (like a.add(3).add(3).mul(3),,,,)</p>
  
  <p>But in my case, only part of methods are accessible after method according to the syntax guide</p>
  
  <p>In example, after A method, A and B method is available. and after B method, B and C method is available.</p>
  
  <p>I implement it like following and success. the type detect and linter are work very well, but I don't think it is the right way to implement.
  <a href="https://playcode.io/376231?tabs=preview,console" rel="nofollow noreferrer">running code is in here</a></p>
  
  <pre class="lang-js prettyprint-override"><code>class ABC {
    private log: string[]
    public constructor() {
      this.log = [];
  
      this.A = this.A.bind(this);
      this.B = this.B.bind(this);
      this.C = this.C.bind(this);
      this.getLog = this.getLog.bind(this);
    }
  
    public A() {
      this.log.push('A');
      return { A: this.A, B: this.B, getLog: this.getLog };
    }
  
    public B() {
      this.log.push('B');
      return { B: this.B, C: this.C, getLog: this.getLog };
    }
  
    public C() {
      this.log.push('C');
      return { C: this.C, getLog: this.getLog };
    }
  
    public getLog() {
      return this.log;
    }
  }
  
  const abc = new ABC();
  const log = abc.A().A().A().B().B().C().getLog();
  console.log('log: ', log);
  </code></pre>
  
  <p>Cause I have to care about return type for every single method since there MIGHT be almost hundreds of methods in class</p>
  
  <p>So what I want is manage all method syntaxes(method availability? list of method accessible after method?) in one single object, and generate class interface according to that syntax.</p>
  
  <p>As you can see in below, I tried to make roughly what I want.
  But maybe because of recursion, this type do not worke correctly :(
  Is there some way to solve this?
  Or is there cool way to provide my requirement?</p>
  
  <p>I think it will be best to have some type 'Chain' like</p>
  
  <p>type a = type Chain</p>
  
  <p>//is same as the type of class ABC that I implemented above</p>
  
  <pre><code>// information of function state machine
  const Syntax = {
    A: {
      next: ['A', 'B'] as const,
    },
    B: {
      next: ['B', 'C'] as const,
    },
    C: {
      next: ['C'] as const,
    },
  };
  
  interface Chain {
    A(): Pick&lt;Chain, typeof Syntax.A.next[number]&gt;;
    B(): Pick&lt;Chain, typeof Syntax.B.next[number]&gt;;
    C(): Pick&lt;Chain, typeof Syntax.C.next[number]&gt;;
    getLog(): string;
  }
  
  class ChainABC implements Chain{
    ~~
  }
  </code></pre>
  
  <p>Re-Attach play code url for class ABC <a href="https://playcode.io/376231?tabs=preview,console" rel="nofollow noreferrer">running code is in here</a></p>