'Express + TypeScript: Create type inference for response.locals

I want to add types for my response.locals. It is used to append data to your request-response cycle.

What I tried

// ./types/express/index.d.ts
declare global {
    declare namespace Express {
        interface Response {
            locals: {
                userId: number;
            };
        }
    }
}

// tsconfig.json
    "compilerOptions": {
        "typeRoots": ["./types"],
    }
myController.post("/", async (request, response) => {
     // Can't get type in my controller
    const { userId } = response.locals; // <- userId is any

Goal: Get correct type inference for my response.locals variable

Versions: "express": "^4.17.1", "@types/express": "^4.17.8", "typescript": "^4.5.4"



Solution 1:[1]

Without a proper TypeScript background, I was able to compile the following (after some trial and error):

import {Request, Response} from "express";
interface Locals extends Record<string, any> {
  userId: number;
}
interface MyResponse extends Response {
  locals: Locals;
}
export function middleware(request: Request, response: MyResponse) {
  const {userId} = response.locals;
  response.end(userId);
  return userId;
}

The declaration file (.d.ts) contains:

export declare function middleware(request: Request, response: MyResponse): number;

so the number type was correctly inferred.

And it works when I use this middleware function in express.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1