I'm trying to build a little function that enables middlewares (Express ones in this case) to transform the `Request` object by adding props to it, so any other following middleware on the chain can use them while maintaining the types.

Maybe it's easier to understand with an example:

```js
app.post(
  '/some/endpoint',
  pipeMiddleware(
    (req, res) => {
      // do some async stuff
      return { entity: { /* ... */ } }
    },
    (req, res) => {
      // do some async stuff
      return { otherEntity: { /* ... */ } }
    },
    (req, res) => handler(req.entity, req.otherEntity, req.body, res)
  )
)

```

So in that case, the second middleware will have access to `entity`, and the third one will have access to both `entity` & `otherEntity`.

I've managed to make it work by doing some ugly stuff like:

```js
type Dict = { [key: string]: any };

export const mw = <
  J extends Request,
  T extends Response,
  R extends Dict,
  K extends Dict | void,
  P extends Dict | void,
>(
  fn1: (a: J, a2: T) => Promise<R>,
  fn2: (a: J & R, a2: T) => Promise<K> = async () => ({} as any as K),
  fn3: (a: J & R & K, a2: T) => Promise<P> = async () => ({} as any as P),
) => async (arg1: J, arg2: T) => {
  const first = Object.assign(arg1, await fn1(arg1, arg2));
  const second = Object.assign(first, await fn2(first, arg2));
  const third = Object.assign(second, await fn3(second, arg2));
  return third;
};

```

And it actually returns the correct types, but I want to make it better by allowing to provide N number of parameters without having to update that function...