next-connect icon indicating copy to clipboard operation
next-connect copied to clipboard

Improve TypeScript interface to catch errors in `NextApiResponse`

Open Kerumen opened this issue 4 years ago • 2 comments

When using next-connect with the generics, we don't have any error if we return a wrongly shaped response:

Screenshot 2020-11-14 at 16 37 24
const handler = nc<NextApiRequest, NextApiResponse>()

handler.get<NextApiRequest, NextApiResponse<{ success: boolean }>>(
  async (req, res) => {
    res.json({ success: '42' })
  }
)

However when we declare types directly in the params, we correctly have the error:

Screenshot 2020-11-14 at 16 37 29
const handler = nc<NextApiRequest, NextApiResponse>()

handler.get(
  async (req: NextApiRequest, res: NextApiResponse<{ success: boolean }>) => {
    res.json({ success: '42' })
  }
)

Can we try to improve the typings of the library to get the error? If we write this it works but I'm not sure that's the good way to fix it.

get<T = {}, S = {}>(...handlers: RequestHandler<U | T, V | S>[]): this;

Kerumen avatar Nov 14 '20 15:11 Kerumen

Hey @Kerumen, sorry for the late response!

get<T = {}, S = {}>(...handlers: RequestHandler<U | T, V | S>[]): this; will probably break the type since TS will not be able to tell if req and res is IncomingMessage and ServerResponse anymore.

This is a fix but I have not tested it out:

// HERE:
const handler = nc<NextApiRequest, NextApiResponse<unknown>>()

handler.get(
  async (req: NextApiRequest, res: NextApiResponse<{ success: boolean }>) => {
    res.json({ success: '42' })
  }
)

This forces the body inside res.json and res.send to only be unknown. Thus, this will break all the remaining res.json/res.send else unless you explicit type it like NextApiResponse<{ success: boolean }>

Let me know if it works for you so I can update the doc with this. Thanks!

hoangvvo avatar Nov 25 '20 04:11 hoangvvo

Thanks for your answer. This works however we must repeat 2 times NextApiResponse and I wanted to avoid that. But it seems it's the only way to do it.

Kerumen avatar Nov 25 '20 14:11 Kerumen