title: How to declare a Stream-like interface in TypeScript?
body: <p>The npm package <a href="https://github.com/wdavidw/node-csv-parse" rel="noreferrer">csv-parse</a> implements a Node.JS Stream like API:</p>
  
  <pre><code>const parser = parse();
  parser.on('readable', () =&gt; {
    let record: any;    // &lt;-- it should be string[]
    while (record = parser.read()) {
      output.push(record);
    }
  });
  </code></pre>
  
  <p>Its <a href="https://www.npmjs.com/package/@types/csv-parse/" rel="noreferrer">type declaration</a> is: </p>
  
  <pre><code>interface parse {
    (options?: options): NodeJS.ReadWriteStream;
  } 
  </code></pre>
  
  <p>The return type of <code>parse</code> is <code>NodeJS.ReadWriteStream</code>, which has a method <code>read</code> returning <code>string | Buffer</code>.</p>
  
  <pre><code>interface ReadWriteStream extends ReadableStream, WritableStream {
    // ...
  }
  
  interface ReadableStream extends EventEmitter {
    read(size?: number): string | Buffer;
    // ...
  }
  </code></pre>
  
  <p>By this definition, I can't define the variable <code>let record: any = parser.read()</code> to its actual type <code>string[]</code>.</p>
  
  <p>I have tried to modify the type definition of csv-parse like this:</p>
  
  <pre><code>interface ParserStream extends NodeJS.ReadWriteStream {
      read(size?: number): string[];    
  }
  
  interface parse {
      (options?: options): ParserStream;
  }
  </code></pre>
  
  <p>It doesn't work because TypeScript not allow to extend an interface and change method's return type.</p>
  
  <p>What I can think of is to change NodeJS Stream to a generic type like:</p>
  
  <pre><code>interface GenericReadableStream &lt;T&gt; extends EventEmitter {
    read(size?: number): T
    // ...
  }
  
  interface ReadableStream extends GenericReadableStream &lt;string | Buffer&gt; {}
  </code></pre>
  
  <p>Then I can define:</p>
  
  <pre><code>interface ParserStream extends GenericReadableStream &lt;string[]&gt; {}
  </code></pre>
  
  <p>I don't know if it's a good way. It impacts a lot in current Node.JS type definitions.</p>