Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve NextApiHandler type for early returns #35166

Merged
merged 2 commits into from Apr 16, 2022
Merged

Improve NextApiHandler type for early returns #35166

merged 2 commits into from Apr 16, 2022

Commits on Mar 28, 2022

  1. Improve NextApiHandler type for early returns

    I would like to be able to write handlers like this
    
    ```typescript
    import { NextApiHandler } from 'next'
    
    const handler: NextApiHandler = (req, res) => {
      const value = getStuff()
      if (value === 'branch') {
        return res.json({}) // return early
      }
      res.status(400)
    }
    ```
    
    but `NextApiHandler`'s current return type is `void | Promise<void>`, which causes compilation to fail with
    
    ```
    Error:(11, 3) TS2322: Type '(req: NextApiRequest, res: NextApiResponse<any>) => Promise<NextApiResponse<any> | undefined>' is not assignable to type 'NextApiHandler<any>'.
      Type 'Promise<NextApiResponse<any> | undefined>' is not assignable to type 'void | Promise<void>'.
        Type 'Promise<NextApiResponse<any> | undefined>' is not assignable to type 'Promise<void>'.
          Type 'NextApiResponse<any> | undefined' is not assignable to type 'void'.
            Type 'NextApiResponse<any>' 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<unknown>` 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:
    ```
    import { NextApiRequest, NextApiResponse } from 'next'
    
    declare module 'next' {
      export declare type NextApiHandler<T = any> = (
        req: NextApiRequest,
        res: NextApiResponse<T>
      ) => unknown | Promise<unknown>
    }
    ```
    bjorndown authored and Björn committed Mar 28, 2022
    Copy the full SHA
    ba159b4 View commit details
    Browse the repository at this point in the history

Commits on Apr 16, 2022

  1. Copy the full SHA
    afab31c View commit details
    Browse the repository at this point in the history