Override res.end with TypeScript Override res.end with TypeScript typescript typescript

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) => {  }};