From c04aebd1bb2cfe52d19142ce2dc944fbb04dc0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn?= Date: Sat, 16 Apr 2022 06:00:52 +0200 Subject: [PATCH] Improve NextApiHandler type for early returns (#35166) I would like to be able to write handlers with early returns like this: ```typescript import { NextApiHandler } from 'next' const handler: NextApiHandler = (req, res) => { const value = getStuff() if (value === 'branch') { return res.json({}) } res.status(400) } ``` but `NextApiHandler`'s current return type is `void | Promise`, which causes compilation to fail with ``` Error:(11, 3) TS2322: Type '(req: NextApiRequest, res: NextApiResponse) => Promise | undefined>' is not assignable to type 'NextApiHandler'. Type 'Promise | undefined>' is not assignable to type 'void | Promise'. Type 'Promise | undefined>' is not assignable to type 'Promise'. Type 'NextApiResponse | undefined' is not assignable to type 'void'. Type 'NextApiResponse' is not assignable to type 'void'. ``` to avoid that the above snippet needs to be written as ```typescript if (value === 'branch') { res.json({}) return } ``` which looks odd to me. Changing the return type of `NextApiHandler` to `unknown | Promise` would allow for shorter early returns and still communicates to users that nothing is expected to be returned from a handler. Augmenting the type like this, makes the first snippet work: ```typescript import { NextApiRequest, NextApiResponse } from 'next' declare module 'next' { export declare type NextApiHandler = ( req: NextApiRequest, res: NextApiResponse ) => unknown | Promise } ``` ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- packages/next/shared/lib/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/shared/lib/utils.ts b/packages/next/shared/lib/utils.ts index 8bafaf0187890..7f152924823ac 100644 --- a/packages/next/shared/lib/utils.ts +++ b/packages/next/shared/lib/utils.ts @@ -267,7 +267,7 @@ export type NextApiResponse = ServerResponse & { export type NextApiHandler = ( req: NextApiRequest, res: NextApiResponse -) => void | Promise +) => unknown | Promise /** * Utils