Override res.end with TypeScript

Problem

Your initial signature does not pass the compiler check, because the end function, which ServerResponse inherits from stream.Writable, has the following overload:

end(cb?: () => void): void;
end(chunk: any, cb?: () => void): void;
end(chunk: any, encoding: string, cb?: () => void): void;

Since the end function has that overload, the compiler is warning you that, at runtime, you need to check which of the overloads is in use.

Solution

Here is a signature that is type safe. It checks which of the three arguments is the callback and then acts accordingly.

import { Response } from 'express';

const handler = (req: Request, res: Response) => {

  res.end = (arg1: Function | any, arg2?: Function | string, arg3?: Function) => {

    if (typeof arg1 === 'function') {
      // end(cb?: () => void): void;
    }

    if (typeof arg2 === 'function') {
      // end(chunk: any, cb?: () => void): void;
    }

    if (typeof arg3 === 'function') {
      // end(chunk: any, encoding: string, cb?: () => void): void;
    }
  }
};

Make your function type to any, this mean it can convert (or assign) to any type.

Try this

res.end = ((data: any, encoding: string): void => { }) as any;

Update

You can make a type what extends express.Response, it overrides end method (the method of NodeJS.WritableStream).

import { Request, Response, Handler } from 'express';

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

interface MyResponse extends Omit<Response, "end"> {
  end: (data: any, encoding: string) => void;
}

const handler: Handler = (req: Request, res: MyResponse) => {
  res.end = (data: any, encoding: string) => {

  }
};