🗂

[Next.js] APIのRequestで受け取ったany型に型を追加してみる

2022/10/02に公開

概要

前回に引き続き、Next.jsでフォームからデータを受けった利する際にAPIでリクエスト(req)とレスポンス(res)の型をTypeScriptではどんな型なのかを調べました。
https://zenn.dev/kiriyama/articles/dcb84e4a021eaa

ただ、アプリケーションによっては、受け取るデータは様々である。
リクエスト(reqNextApiRequestとなるが、bodyに関してはany型となっている。
anyの型自体は何でも指定できるので良いが、あまりanyは推奨されてないので、NextApiRequestに新たなデータの方を追加してみる。

前提

まず前提として、ユーザー登録するとして、名前/メールアドレス/パスワードが必要になった例として以下のフォームがあった場合。

<form action="http://localhost:3000/api/user/register" method="post">
     名前:<input type="text" name="name"><br>
     メールアドレス:<input type="text" name="email"><br>
     パスワード1:<input type="text" name="password"><br>
     <button type="submit">ユーザー登録</button>
 </form>
api/user/resigter
const registerUser = async (req,res) => {
 console.log(req.body)
};

export default registerUser;

Next.jsのAPIのリクエスト(req)で受け取ったデータのbodyをコンソールで出力してみると以下のように表示される。

[Object: null prototype] {
  name: 'こちらは名前',
  password:'testtest0987'
  email: 'testtest@gmail.com'
}

NextApiRequest.bodyについて

実際にbodyについてですが、リクエスト(req)の型は前回の記事で説明したとおり、NextApiRequestとなるが、bodyに関してはany型となっている。
これは最初に説明したようにアプリケーションによってリクエスト(req)で受け取るデータが違うのでNex.js側で予め型が決められない為。

VSCodeを使ってる場合、bodyにカーソルを当てると型を表示してくれる。(下記の画像)

またNext.jsの型情報が記載されてるutils.d.tsというファイルを見るとNextApiRequestbodyanyになってるのが確認できる。

NextApiRequestを継承して拡張する

実際に新たなデータの方を追加するにはextendsを使った継承させて拡張することができる。
その為、interfaceを使って継承させる。
もちろんtypeでも継承っぽいことはできるが今回はinterfaceで。

api/user/resigter
import type { NextApiRequest, NextApiResponse } from 'next'

interface ExtendNextApiRequest extends NextApiRequest{
    body:{
        email:string
    }
}

const registerUser = async (req:ExtendNextApiReques,res:NextApiResponse) => {
 console.log(req.body)
};

export default registerUser;

上記のようにbodyemailを文字型stringとして追加して、registerUserの引数のリクエスト(req)に拡張したExtendNextApiRequestを型として指定する。

まとめ

今回はany型なのでスルーしてもいいのかもしれないけど、こういった方法もあるのかと勉強していて思ったのでメモとして残した。
ちなみにtypeの場合も下記の記事を参考にするのもいいかもです。

https://yutaro-blog.net/2021/10/08/typescript-interface-type/#index_id6

Discussion