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