【TypeScript】型安全なAPIレスポンスの実装

【TypeScript】型安全なAPIレスポンスの実装

投稿日: 2025年01月17日

学習振り返り
Tips
要約
  • TypeScriptを使用することで、APIリクエストとレスポンスの型を明示的に指定し、型安全性を確保できる。
  • 型を指定することで、プロパティの追加や変更時にエラーが早期に発見でき、開発効率が向上する。
  • 型指定が習慣化されることで、エラーのリスクを減らし、安心して開発できる環境を整えることができる。

はじめに

TypeScriptについて前回は推論について書きましたが、今回はAPIレスポンスに特化して型を味方にして型安全を担保する方法について書いてみます。

このあたりが理解できて使えるようになると、エンドポイントを作成するときにまず型を書くことが習慣化してきて、めんどくさいではなく自分のために書くようになります。

↓前回のTypeScriptの記事

テーマ

既存のエンドポイントを元に「この機能を追加したいからレスポンスにこのデータも含めよう!」ってなった時に、型をしっかり指定している時の楽さと、指定していない時のリスクについて取り上げます。

というのも、最近開発しているアプリでまさにこのパターンありまして、「ほんとTypeScript最高!JavaScriptもう怖くて書けないかも」って改めて感じたのです笑

元の型

import { Homework, LongVacation } from "@prisma/client";
export type Data = {
  child: {
    id: string;
    name: string;
  };
  homeworks: Homework[];
  longVacation: LongVacation | null;
};
export type DashboardResponse = { data: Data[] };

型の指定

基本的なことになりますが、まずは型の指定についてです。

バックエンド

バックエンドでは、`NextResponse.json`に型引数を渡して、レスポンスの型を明示的に指定します。

return NextResponse.json<DashboardResponse>(
      {
        data,
      },
      { status: 200 }
);

フロントエンド

フロントエンドでは、`fetch`で取得したデータを`json`に変換する際に型を指定します。

const data:DashboardResponse  = await resp.json();

ちなみに・・
ちょくちょく、下記のようにされている方を見かけます。

const data = await resp.json();
const {data}:DashboardResponse  = data;

こうすると、dataがany型になってしまうため、型安全性が低下します。
await resp.json();の結果がどのような型であるかが明示されないため、その後の処理で予期しないエラーが発生する可能性があると思います。
await resp.json();の時点で型の指定をした方が良いと思います。

このレスポンスの型をバックエンドとフロントエンドで共通のものを使うというのが重要です!別で定義してはダメとは言わないけどダメです!!w

このように型を指定していることを前提に、レスポンスにデータを追加したいなぁとなった時が今回のお話です。

追加した後の型

import { Homework, LongVacation } from "@prisma/client";
export type Data = {
  child: {
    id: string;
    name: string;
  };
  progress: number;  //追加
  homeworks: Homework[];
  longVacation: LongVacation | null;
};
export type DashboardResponse = { data: Data[] };

その時、エディターでバックエンドのファイルがエラーを吐きます!!

API接続の型安全について|ShiftBブログ

レスポンスに含めないといけない追加したプロパティがないよって教えてくれます🤩
赤いから絶対修正しますよね!!
親切にエラー吐いてくれるのでTypeScript最高です。

これ、TypeScriptで書いていたとしてもレスポンスの型を指定をしていないとなんでもreturnできてしまうためにエラー吐いてくれないので、レスポンスに含めないままフロント側で存在するものとして処理を書いたらundefindeになって処理できずにエラー吐くみたいなことが起こる可能性があります。(他の箇所で一部型使ってるとそっちでエラー吐くことはあります)

この例のパターンはフロントエンド側は赤くならない(元々あるものとして処理を書いていないので)ですが、命名の変更とかですでに存在しているプロパティの型に変更を加えるとバックエンドもフロントエンドも赤くなります。

やってみます。
フック使ってデータ取得しているのでちょっとわかりにくいです💦

元がこれです。(左:バックエンド、中:型、右:フロントエンド)

API接続の型安全について|ShiftBブログ

型のプロパティ名を変える

import { Homework, LongVacation } from "@prisma/client";
export type Data = {
  child: {
    id: string;
    name: string;
  };
  progres: number; //progress→progresにしてみる
  homeworks: Homework[];
  longVacation: LongVacation | null;
};
export type DashboardResponse = { data: Data[] };

その結果・・・

API接続の型安全について|ShiftBブログ

吐きました!!!!
しかもエラーメッセージ親切・・!

API接続の型安全について|ShiftBブログ

型指定していないと、配列処理する際にエラー吐いてるのも結構見かける気がします。
mapの引数の値の型がanyになるというエラーでるパターン多い気がします。

まとめ

推論されるところは基本的に指定する必要ありませんが、指定しないとanyになるとかunknownになるところはどんどん指定して楽しましょう。
エラー吐いてくれて安全に書けるということもありますが、推論も働くのでタイポしてundefindeということもなくなります。


型指定をすることで、開発中のエラーを早期に発見でき、結果として開発効率が向上します。
慣れたり良さが理解できるまでは手間だよと思うかもしれませんが、慣れたら絶対型は味方になるので慣れるまで耐えて書きましょうw

おわりに

既存のコード使ったため、解説用にコード書かなかったので微妙カモしれないですが便利さ伝わっていたらいいな・・と思います。
どういうこと??ってなったらDMくださいw

シェア!

Threads
user
吉本茜
山口在住/二児の母/育休中
Loading...
記事一覧に戻る
Threads
0