5

I have an anonymous function in Express like so:

app.use((err, req, res, next) => {
  // ...
});

and I want to set the type of the function to ErrorRequestHandler (Not the return type!).

I can do it like this:

const X: ErrorRequestHandler = (err, req, res, next) => {
  // ...
}
app.use(X);

But is there a syntax to do it inline? Like this:

app.use((err, req, res, next) => {
  // ...
} : ErrorRequestHandler); // Note: this doesn't work.
13
  • 1
    Type inference should be correct and no annotation should be required Commented Jan 23, 2021 at 14:41
  • 1
    @AluanHaddad That's what I first thought would happen too, but with Express types are not inferring automatically here. I assume it's because app.use has overlaps with parameter count here, so Typescript can't determine which one you want from parameter count only. Commented Jan 23, 2021 at 14:50
  • 1
    @Keith that's interesting. Perhaps if you specify the parameter types, that will be sufficient Commented Jan 23, 2021 at 14:52
  • 1
    @AluanHaddad Just tried it, unfortunately you then have to put all parameters types in, and then that kind of defeats the whole point of casting it. Using the extra brackets and cast as ErrorRequestHandler seems to be the most succinct way I can find. Commented Jan 23, 2021 at 14:57
  • 1
    @AluanHaddad No problem, I currently can't make it fail, but if there is a gotcha it would be great to know, and I could add it as gotcha on my answer. Hate to think this is a hack ready to fail. I wonder what express dev's suggest, as the implicit typing is not working for this case. ps. things like app.get('/', (req, res) => {}) work fine though. Commented Jan 23, 2021 at 15:17

2 Answers 2

5

You just need to use some extra brackets to help Typescript out.

eg..

app.use(<ErrorRequestHandler>((err, req, res, next) => {
}));

You can of course use as too, to avoid any JSX confusion.

app.use(((err, req, res, next) => {
}) as ErrorRequestHandler);

Notice how above the whole function is enclosed inside brackets, this allows Typescript to apply the typecast to the whole function expression.

Code completion on req, res, & next will then work as expected.

Sign up to request clarification or add additional context in comments.

Comments

0

typescript anonymous function type

lass Foo {
    save(callback: (n: number) => any) : void {
        callback(42);
    }
}
var foo = new Foo();

var strCallback = (result: string) : void => {
    alert(result);
}
var numCallback = (result: number) : void => {
    alert(result.toString());
}

foo.save(strCallback); // not OK
foo.save(numCallback); // OK

1 Comment

I get you, the problem with this though is that I cannot specify the type of app.use, that's built into Express

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.