typescript and express js. change res json `Response` type

Viewed 5888

in typescript, I am trying to overwrite the express's Response json object to be a specific type of object to always be used

for example, I want to enforce a interface type that would error out if the following format was not followed

  return res.status(200).json({
    data: ["a", {"a": "b"}],
    success: true,
  });

I attempted to use dts-gen --m express -f src/types/express.d.ts to create the declaration file to modify but it ended in failure.

is there a way to overwrite a specific type on an existing library or do I need to create a declaration file specific to my needs?

3 Answers

You can set custom types in generic types of req and res objects such a:

import type * as E from 'express';

interface CustomResponseType {
  test: string;
}

export default async function Example(
  req: E.Request<undefined, CustomResponseType, [CustomReqBodyType?], [CustomReqQueryType?]>,
  res: E.Response<CustomResponseType>
): Promise<E.Response<CustomResponseType, Record<string, any>>> {
  return res.status(200).json({ test: 'success' });
}
interface Json {
  success: boolean;
  data: any[];
}

type Send<T = Response> = (body?: Json) => T;

interface CustomResponse extends Response {
  json: Send<this>;
}

I was able to create a new interface that extended this. just needed to learn a bit more :) hopefully this can help out someone else!

Just an extend reply, if you want to explicit define type for response, you can do like this

// overlap the ResBody = any (from Express module) to the exact type 
// you want in CustomResponse

type Send<ResBody = any, T = Response<ResBody>> = (body?: ResBody) => T;

export interface CustomResponse<T> extends Response {
   json: Send<T, this>
}

then you can import in the controller function:

async (req: Request, res: CustomResponse<IUser>, next: NextFunction) =>

Your res.json() will strictly stick to the IUser Interface.

Related