compose-middleware icon indicating copy to clipboard operation
compose-middleware copied to clipboard

Type 'Next<void>' is not assignable to type 'NextFunction'

Open twrayden opened this issue 5 years ago • 7 comments

I am using Typescript v4.0.2 and I am getting a type error when trying to use third party middleware that uses the NextFunction type from @types/express.

Culprit code:

// Next & NextFunction are not compatable and no way to overwrite with generic
type Next<T = void> = (err?: Error | null) => T;

type RequestHandler<T, U, V = void> = (req: T, res: U, next: Next<V>) => V;

I recommend something like:

type RequestHandler<TRequest, TResponse, TNext, TReturn> = (req: TRequest, res: TResponse, next: TNext) => TReturn;

twrayden avatar Sep 08 '20 10:09 twrayden

If you'd like to create a PR with a reproduction, I can review it. However, just accepting a TNext isn't suitable since it should be a function.

blakeembrey avatar Sep 09 '20 15:09 blakeembrey

I'm confused now, I tried to replicate it in Typescript Playground and it works fine with no type errors...

// Taken from compose-middleware
type Next<T = void> = (err?: Error | null) => T;

// Taken from @types/express
interface NextFunction {
    (err?: any): void;
    (deferToNext: "router"): void;
}

const n: NextFunction = (err?: any) => {
    if (err) {
        console.log("error", err);
    }
    console.log("hello");
};

function compose(next: Next) {
    next();
}

compose(n); // No type errors

twrayden avatar Sep 10 '20 01:09 twrayden

I'm totally fine if you need to create a PR that uses @types/express to reproduce the problem 😄 Just want to make sure it's captured accurately to make sure we can avoid regressions in the future.

blakeembrey avatar Sep 11 '20 03:09 blakeembrey

I have the same issue. Any plans to get this merged?

menocomp avatar Dec 15 '20 03:12 menocomp

Faced the same issue. I'm trying to pass https://github.com/auth0/express-jwt middleware to compose and get error

Argument of type 'RequestHandler' is not assignable to parameter of type 'Handler<Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, Response<any, Record<string, any>, number>, void>'

since request handler from @types/express is not compatible with RequestHandler from compose-middleware.

import {RequestHandler} from 'express';
import {compose} from "compose-middleware";

const mw: RequestHandler = (req, res, next) => {}

compose(mw) // Error ts(2345)

misha-erm avatar Dec 17 '21 13:12 misha-erm