👻

TypeScript×Next.js×Reactで環境変数を使う方法

2024/03/04に公開

はじめに

こんにちは。チョコ柿と申します。
今回はタイトルにもあるとおり、TypeScript×Next.js×Reactで環境変数を使う方法をAPIでデータをfetchする例を用いて書いていこうと思います。

ちなみに使うAPIは映画情報取得のために、TMDBのAPIをお借りします。

ではでは!

.env.localファイルに情報を記載する

まずは.env.localファイルをルートディレクトリに作成します。
作成したら中身にAPI取得用のURLなどを記載します。
(もしかしたらAPIkeyもここで定義するかもしれませんが、今回の例ではAPIに含まれています)

NEXT_PUBLIC_TMDBURL = https://api.themoviedb.org/XX~

ここで"NEXT_PUBLIC"を使うのを忘れないようにしてください!
これはクライアント側でこのAPI取得URLを使うための、Next.jsのルールです。
これを忘れると使うことができません。サーバー側では使えたりします。

実際にAPIでデータを取得する

localファイルに情報を記載したら、APIでデータを取得するためのコードを書いていきます。

型アノテーション

まず大枠をざっと書きます。Jsで書ける範囲です。

import React, { useEffect, useState } from "react";

const Tmdb = process.env.NEXT_PUBLIC_TMDBURL;

export const useFetchData = () => {
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch(Tmdb);
      const jso = await res.json();
    };

    fetchData();
  }, [Tmdb]);

  return data;
};

ここまで書くとfetch(Tmdb)のところに「オーバーロードが一致しません」というエラーメッセージが出ました。

今回だと
「この呼び出しに一致するオーバーロードはありません。
2 中 1 のオーバーロード, '(input: string | URL | Request, init?: RequestInit | undefined): Promise<Response>' により、次のエラーが発生しました。
型 'string | undefined' の引数を型 'string | URL | Request' のパラメーターに割り当てることはできません。
型 'undefined' を型 'string | URL | Request' に割り当てることはできません。
2 中 2 のオーバーロード, '(input: URL | RequestInfo, init?: RequestInit | undefined): Promise<Response>' により、次のエラーが発生しました。
型 'string | undefined' の引数を型 'URL | RequestInfo' のパラメーターに割り当てることはできません。
型 'undefined' を型 'URL | RequestInfo' に割り当てることはできません。ts」
というエラーが出ました。長すぎです。

要約すると、"Tmdb"の型が不明瞭なのでエラー吐いてるよって感じです。
そのためTmdbに型アノテーションをしてあげます。
const Tmdb: string = process.env.NEXT_PUBLIC_TMDBURL;
stringをつけてみました。すると
「型 'string | undefined' を型 'string' に割り当てることはできません。
型 'undefined' を型 'string' に割り当てることはできません。」
またエラーが出ました。

これは「stringかundefinedが来る可能性があるので、stringっていう指定はできないよ」と言ってくれているようです。

ただ、今回作るプロダクト的にこのAPIがundefinedになることは想定していないので、非null演算子を使ってこのエラーを解消したいと思います。
const Tmdb: string = process.env.NEXT_PUBLIC_TMDBURL!;
末尾に「!」をつけました。
こうすることで、undefinedにはならないよとTypescriptに伝えることができます。

条件分岐の例も追記しておきます。

let Tmdb: string;

if (typeof process.env.NEXT_PUBLIC_TMDBURL === "string") {
  Tmdb = process.env.NEXT_PUBLIC_TMDBURL;
} else {
  throw new Error("NEXT_PUBLIC_TMDBURL is not defined");
}

と、こんな感じで指定するとオーバーロードも型が定められて解決することになります。

終わりに

皆様の何かの参考になれば幸いです。
間違いやご指摘あれば暖かくコメントいただけると泣いて喜びます。
それでは!!

Discussion