1

I'd like to add a prototype function to NodeJS.ReadableStream. Here is my attempted code along with resulting errors.

my.d.ts

declare namespace NodeJS {
    interface ReadableStream {
        readAll(encoding: string): Promise<string>;
    }
}

my.ts

namespace NodeJS {
    ReadableStream.prototype.readAll = function (this: ReadableStream, encoding: string) {
        // do stuff
    };
}

Errors

  • lib.es6.d.ts: Property 'readAll' does not exist on type 'ReadableStream'.

    I'm not sure how to properly reference NodeJS ReadableStream interface instead of the lib.es6's ReadableStream interface within my.ts. I tried to provide scoping by means of namespace NodeJS, but it does not work.

  • node\@types\index.d.ts: Class 'Readable' incorrectly implements interface 'ReadableStream'. Property 'readAll' is missing in type 'Readable'.

Related

Note, I tried using my learning from How to extend String Prototype and use it next, in TypeScript question, but haven't arrived at a solution.

Edit #1

As requested, here's the code from node\@types\index.d.ts that is producing the second error. The last line where Readable class is defined is specifically the error. The code is sourced from dependency "@types/node": "^8.5.8". Note, I feel this is the pertinent code from the 7000+ line file and won't be pasting the rest. You can view it in full glory here.

declare module "stream" {
    import * as events from "events";

    class internal extends events.EventEmitter {
        pipe<T extends NodeJS.WritableStream>(destination: T, options?: { end?: boolean; }): T;
    }

    namespace internal {
        export class Stream extends internal { }

        export interface ReadableOptions {
            highWaterMark?: number;
            encoding?: string;
            objectMode?: boolean;
            read?: (this: Readable, size?: number) => any;
            destroy?: (error?: Error) => any;
        }

        export class Readable extends Stream implements NodeJS.ReadableStream {

Edit #2

Working through the suggestions in the comments, I've arrived at the following code, which solves both of the original compiler errors. However, another error is popping up at run-time, myReadableStreamVariable.readAll is not a function.

my.ts

declare namespace NodeJS {
    interface ReadableStream {
        readAll: typeof readAll;
    }
}

function readAll(this: NodeJS.ReadableStream, encoding: string) {
    // do stuff
};

hack.ts

import { Readable } from "stream";

declare module "stream" { interface Readable extends NodeJS.ReadableStream { } }
Scott Lin
  • 1,532
  • 1
  • 18
  • 28
  • The problem is that you have both a declaration file and a source file with the same name. The compiler will only consider one of them, preferring the source file, so the method you're declaring is being ignored. – Aluan Haddad Apr 05 '18 at 00:24
  • 2
    I've answered a very similar question in some detail before https://stackoverflow.com/q/43667085 – Aluan Haddad Apr 05 '18 at 00:30
  • @AluanHaddad, thanks. Your other answer helped me resolve the first error. Now I need to find a solution for the second error. – Scott Lin Apr 05 '18 at 01:13
  • Can you update your question with the code that's giving you the error? I'm not entirely clear on what it looks like. Also if the other answer helped you why not vote for it ;)? – Aluan Haddad Apr 05 '18 at 01:39
  • @AluanHaddad, as you wish. – Scott Lin Apr 05 '18 at 03:56
  • This is weird. I saw definitely see the error and the only way I could fix it was by adding an augmentation `declare module "stream" {interface Readable extends NodeJS.ReadableStream {}}`(in a _module_). But, AFAIK this shouldn't be necessary. – Aluan Haddad Apr 05 '18 at 04:15
  • Interesting. Your latest suggestion made the compiler happy, but at runtime, the error `myReadableStreamVariable.readAll is not a function` pops up. Edit: I will post my most recent code in a minute. – Scott Lin Apr 05 '18 at 05:58

0 Answers0