title: Typescript - Creating custom express middleware definition
body: <p>I've been having a real difficult time trying to define custom middleware for our app. I'm using typescript@3.6.3 and express@4.17.1.</p>
  
  <p>All the examples I've been seeing for typing middleware implies that the user is not adding anything to the <code>req</code> or <code>res</code> argument, but I know that that was kind of the point of middleware - mutate either one of those objects knowing that the middlewares had to be loaded in a certain order (ie. cookie-parser or body-parser was notorious for this in the early days, i guess still is?). Anyway, most of the examples net out to something like this github issue: <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26146#issuecomment-393386416" rel="noreferrer">https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26146#issuecomment-393386416</a></p>
  
  <p>The problem I have with that is that we do mutate the <code>req</code> and <code>res</code> objects being passed along to each middleware so I've had to type both objects accordingly:</p>
  
  <pre class="lang-js prettyprint-override"><code>import {
      Express as ExpressInterface,
      Request as ExpressRequest,
      Response as ExpressResponse,
      NextFunction as ExpressNextFunction,
  } from 'express';
  import LoggerType from 'some-log-package';
  
  // don't do anything different the `next()`
  export type ExpressNextFunction = ExpressNextFunction;
  
  export interface CustomServerApp extends ExpressInterface {
      customHeader: string;
      customLogger: LoggerType;
  }
  
  export interface CustomServerRequest extends ExpressRequest {
      app: CustomServerApp,
      id: string,
      urlSearchParams: URLSearchParams,
      // etc
  }
  
  export interface CustomServerResponse extends ExpressResponse { ... }
  </code></pre>
  
  <p>So I export the basic arguments for middleware:</p>
  
  <ul>
  <li><code>req</code> = <code>CustomServerRequest</code></li>
  <li><code>res</code> = <code>CustomServerResponse</code></li>
  <li><code>next</code> = <code>ExpressNextFunction</code></li>
  </ul>
  
  <p>Of course, I import those accordingly to my middleware files:</p>
  
  <pre class="lang-js prettyprint-override"><code>import {
      CustomServerRequest,
      CustomServerResponse,
      ExpressNextFunction
  } from './server-types'
  
  export const customMiddleware = (req: CustomServerRequest, res: CustomServerResponse, next: ExpressNextFunction): void {
      // do something here with either `req` or `res` or both!
      next()
  };
  
  </code></pre>
  
  <p>We have a centralized <code>middleware.ts</code> file where we put all of our global middleware into so it looks something like this:</p>
  
  <pre class="lang-js prettyprint-override"><code>import { CustomServerApp } from './server-types';
  import { customMiddleware } from './middlewares/customMiddleware';
  export const middlewares = (app: CustomServerApp): void =&gt; {
      app.use(
          customMiddleware,
          // maybe more middlewares, etc
      );
  }
  </code></pre>
  
  <p>However, then the type checker runs, I get errors like the following:</p>
  
  <pre><code>No overload matches this call.
    The last overload gave the following error.
      Argument of type '(req: Request, res: Response, next: NextFunction) =&gt; void' is not assignable to parameter of type 'PathParams'.
        Type '(req: Request, res: Response, next: NextFunction) =&gt; void' is missing the following properties from type '(string | RegExp)[]': pop, push, concat, join, and 27 more.ts(2769)
  </code></pre>
  
  <p>I've been having a real tough time understanding why this is getting caught on the last overload definition. Just based on the <code>@types/express</code>, it seems hard to add an additional overload to middleware handler even with type declaration merging. </p>
  
  <p>Even when I follow a similar pattern to the core express types to define a middleware handler - <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-serve-static-core/index.d.ts#L40-L43" rel="noreferrer">https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-serve-static-core/index.d.ts#L40-L43</a> - it doesn't work out either. It also doesn't seem like it's easy to <code>extend</code> from either - <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express/index.d.ts#L99" rel="noreferrer">https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express/index.d.ts#L99</a> - since you can't pass a generic to the core RequestHandler, unlike the router definitions (<code>IRouterHandler</code>, <code>IRouterMatcher</code>). When I try and type it this way, I get different, but similar type errors.</p>
  
  <p>Has anyone else experienced doing something similar?</p>