express icon indicating copy to clipboard operation
express copied to clipboard

Can't use custom type for Request and Response objects in Express 5

Open randomprogramming opened this issue 1 year ago • 2 comments

Hi. I am trying to use a custom middleware which injects the users company in either the request or response objects. I don't want to use declare global for this, as not all of my requests in the app will use this custom middleware. I tried a couple of things, and everything gives me some sort of typescript error

export interface CompanyReq extends Request {
    company: Company;
}

export default function (companyRepository: CompanyRepository) {
    return async (req: CompanyReq, _res: Response, next: NextFunction) => {
        const company = await companyRepository.findByAccountId(req.user.id);
        if (!company) {
            throw new CompanyNotFound();
        }
        req.company = company;
        next();
    };
}
this.router.get(
            "/",
            [hasCompany(companyRepository)],
            this.getCompany
        );

I also tried all of these interfaces:

export interface CompanyReq extends Request {
    company: Company;
}

export interface MyResp extends Response {
    locals: {
        company: Company;
    };
}

interface ResLocals extends Record<string, any> {
    company: Company;
}

export interface Responsee<ResBody = any, Locals extends Record<string, any> = Record<string, any>>
    extends core.Response<ResBody, Locals> {

    locals: ResLocals & Locals;
}

export interface Responseeee extends Response {
    locals: Record<"company", ResLocals>;
}

Nothing works. All errors are something along the lines of this one:

Types of property 'locals' are incompatible.
              Property 'company' is missing in type 'Record<string, any> & Locals' but required in type '{ company: GetResult<{ id: string;}, unknown> & {}; }'.

How to properly extend either the request or response objects?????

randomprogramming avatar Jul 18 '23 15:07 randomprogramming

Hi, I'm new to open source contribution, how can i solve issue.

  1. I have taken pull of the express code but how can I go to issue and solve it.

SHarpreetSingh avatar Jul 19 '23 12:07 SHarpreetSingh

I'm afraid that you have to extend the Request interface from Express namespace globally (as an optional property), because modifying request or response is a side-effect that can't be expressed in TypeScript.

FYI Express type definitions are maintained in the DefinitelyTyped project and there are no Express 5 specific definitions (I think that the v4 types should be good enough for most use cases).

krzysdz avatar Jul 19 '23 20:07 krzysdz