express icon indicating copy to clipboard operation
express copied to clipboard

Typings for Send accept a Promise but the function doesn't await it

Open Sainan opened this issue 9 months ago • 3 comments

Environment information

Version: 5.0.1 (latest) Platform: Windows 10 (x86_64) Node.js version: 22.14.0 TypeScript version: 5.5.4

What steps will reproduce the bug?

const getData = async (): Promise<Record<string, string>> => {
    return { hello: "world" };
};

router.get("/test", (_req, res) => {
    res.json(getData());
});

This compiles successfully but the response will be {}.

I expected either a compiler error or for the response to be {"hello":"world"}.

Sainan avatar Mar 12 '25 09:03 Sainan

Where are you seeing that send accepts a Promise?

The typing indicates that it accepts a ResBody which is typed as any, not Promise<any>. A Promise is tolerated, but not explicitly documented:

export type Send<ResBody = any, T = Response<ResBody>> = (body?: ResBody) => T;

The send method is not asynchronous, so this looks like expected behavior to me. You'll need to await your data before sending it in the response.

As for why TypeScript doesn't complain, that is a limitation of using any as the type.

Perhaps a stricter type could be entertained in a future version but for now, this is expected.

dpopp07 avatar Mar 12 '25 15:03 dpopp07

Yes, I say it's accepted due to the fact that it's not a compiler error. I thought it should probably be resolved one way or the other as this could otherwise result in some hard-to-find bugs.

Sainan avatar Mar 12 '25 15:03 Sainan

I guess another possible fix would be to throw a runtime error if a promise is given. That would still be preferable to such a silent failure.

Sainan avatar Mar 12 '25 15:03 Sainan