Next.jsで学ぶReact講座(完全初心者向け・30日) | 第5章:仕上げと次の一歩 – TypeScript超入門(必要最低限)

React Next.js
スポンサーリンク

この章でやる「TypeScript超入門」のゴール

ここでは、Next.js × React を「実務に耐えるレベル」にぐっと近づけるために、TypeScript の必要最低限だけを押さえます。

やることはこの4つです。

  • 型ってそもそも何者か
  • props に型を付ける基本
  • useState に型を付ける基本
  • 型エラーに慣れるための考え方

「TypeScript 全部わかるようになる」必要はありません。
「何となく怖い存在」から「むしろ守ってくれる存在」に変われば、この章の目的は達成です。


型とは

「その変数にどんな形の値が入るのか」という約束

TypeScript の「型」は、一言でいうと

「この変数には、こういう種類の値が入ります」という約束

です。

JavaScript では、こんなコードも通ってしまいます。

let count = 0;
count = "こんにちは"; // 実行時まで怒られない
JavaScript

TypeScript では、これにブレーキをかけます。

let count: number = 0;
count = "こんにちは"; // コンパイル時にエラー
TypeScript

ここで、

  • : number が「この変数には数値しか入れません」という宣言
  • "こんにちは"(文字列)を入れようとすると型エラー

という仕組みです。

エラーは「うるさい教師」じゃなくて、
「あなたが未来でハマりそうなバグを、今のうちに止めてくれる存在」です。

よく使う基本の型だけ覚えればOK

最初に覚える型は、これくらいで十分です。

  • string … 文字列(”hello”)
  • number … 数値(0, 3.14)
  • boolean … 真偽値(true / false)
  • string[] … 文字列の配列
  • number[] … 数値の配列
  • { ... } … オブジェクト(後でやる)

例えば:

let title: string = "Next.js 入門";
let age: number = 20;
let isDone: boolean = false;
let tags: string[] = ["React", "Next.js"];
TypeScript

これ以上を一気に覚えようとしないで大丈夫です。
実務でも、このあたり+オブジェクト型を組み合わせるのがほとんどです。


propsの型

コンポーネントの「引数の形」を型で表現する

React コンポーネントは、普通の関数です。

function Greeting(props) {
  return <p>こんにちは、{props.name}さん</p>;
}
TSX

TypeScript では、この props にも「型」を付けます。
「このコンポーネントは、こういう props を受け取ります」という契約です。

type GreetingProps = {
  name: string;
};

function Greeting({ name }: GreetingProps) {
  return <p>こんにちは、{name}さん</p>;
}
TSX

ここでの重要ポイントは、

  • type GreetingProps = { name: string } で「props の形」を定義
  • コンポーネントの引数 { name }: GreetingProps を付ける

です。

こうすると、

<Greeting name="太郎" />      // OK
<Greeting />                 // エラー:name 必須なのに渡してない
<Greeting name={123} />      // エラー:name は string 型なのに number 渡してる
TSX

というチェックを、実行前にコンパイラがしてくれます。

props が複数ある場合

例えば、こういうカードコンポーネントを考えます。

type LessonCardProps = {
  title: string;
  level: "初級" | "中級" | "上級";
  description?: string;
};
TSX

ここでは新しいポイントが2つあります。

レベルを文字列リテラルで絞る

level: "初級" | "中級" | "上級";

これは、「level に入れていいのはこの3つのどれかだけ」という意味です。

<LessonCard title="React基礎" level="初級" />    // OK
<LessonCard title="React基礎" level="中級" />    // OK
<LessonCard title="React基礎" level="上級" />    // OK
<LessonCard title="React基礎" level="超上級" />  // エラー
TSX

「文字列タイポによるバグ」をかなり減らせるので、実務でもよく使うパターンです。

? で「省略可能な props」を表す

description?: string;

これは、「あってもいいし、なくてもいい」という意味です。

<LessonCard title="React基礎" level="初級" />                       // OK(description なし)
<LessonCard title="React基礎" level="初級" description="入門編" />   // OK
TSX

省略可能な props かどうかをハッキリさせられるのも、TypeScript の良いところです。


useStateの型

基本は「初期値から型を推論してもらう」

useState に型を付けるとき、一番楽なのは「初期値から推論してもらう」ことです。

const [count, setCount] = useState(0);           // number と推論される
const [name, setName] = useState("太郎");       // string と推論される
const [items, setItems] = useState<string[]>([]); // これは明示している
TSX

上の2つは、初期値から勝手に型が決まるので、わざわざ <number> と書かなくてOKです。

配列や少し複雑な型のときは、明示してあげることが多いです。

配列の state に型を付ける

TODO リストなどの配列 state は、TypeScript のよくあるケースです。

type Todo = {
  id: number;
  text: string;
  done: boolean;
};

const [todos, setTodos] = useState<Todo[]>([]);
TSX

ここで、

  • Todo という型で 1 件分の TODO の形を定義
  • Todo[] で「Todo 型の配列」と宣言

という形にしています。

これで、

setTodos([
  ...todos,
  { id: 1, text: "勉強する", done: false }, // OK
]);

setTodos([
  ...todos,
  { id: 2, text: "本を読む" },              // エラー:done が足りない
]);
TSX

のようなチェックが効くようになります。

null を許容する state

「まだ値がない」状態を表したいとき、null を使うことがあります。

例えば「選択中の TODO」の state。

const [selectedId, setSelectedId] = useState<number | null>(null);
TSX

ここでは、

  • 最初は何も選ばれていないので null
  • 何かを選んだら setSelectedId(その id)

という動きをします。

number | null は、「number か null のどちらか」という意味です。

コンポーネント内で使うときは、

if (selectedId === null) {
  return <p>TODO が選択されていません。</p>;
}

// ここから先は selectedId は number として扱える
TSX

のように、null チェックを入れるのが TypeScript 的には大事になります。


型エラーへの慣れ

最初は「エラーが増えた」と感じて当然

TypeScript を入れると、最初はこう感じやすいです。

  • 「さっきまで動いていたコードが、コンパイルエラーで止まる」
  • 「赤線だらけで心が折れそう」

これは、TypeScript が今まで見逃していた危険なコードを可視化しているだけです。

実行時に落ちるはずだったところを、
「保存した瞬間」に教えてくれている、とも言えます。

型エラーを「メンターだと思って読む」

型エラーは、たいていかなり親切に書かれています。

例:

Type 'string | undefined' is not assignable to type 'string'.
→「string か undefined が来る可能性があるけど、ここは string 一本じゃないとダメだよ」

このときの思考としては、

  • 「なぜ undefined が混ざっているんだろう?」
  • 「この値は本当に必ず存在する? それとも存在しない場合もある?」
  • 「undefined を許容する型に広げるべきか、事前にチェックすべきか?」

といった問いを立てていきます。

「うるさい!」ではなく、
「この人は何を心配してくれてるんだろう?」と読み解く感じです。

少しずつ「型を先に設計する」感覚へ

慣れてくると、

  • API からどんな形の JSON が返ってくるか型で表す
  • その型をもとに画面の設計をする

という「型から考える」スタイルが取れるようになってきます。

でも、今はそこまで行かなくていいです。
まずは、

  • props に型を付ける
  • useState に型を付ける
  • 型エラーが出たら「何を心配しているか」を読んで直す

ここだけできれば、実務の入口には十分立てます。


まとめと、TypeScriptと仲良くなるために

ここまでのポイントを整理すると、

  • 型とは「この変数にはこういう種類の値が入る」という約束で、バグを事前に止めてくれる
  • props は type Props = { ... } で形を定義し、function Component(props: Props) のように型を付ける
  • useState は基本的に初期値から推論されるが、配列やオブジェクトは useState<T[]>([])useState<T | null>(null) など明示すると安心
  • 型エラーは「将来のバグ予告」であり、何を心配しているかを日本語にして読むことで、徐々に強力な味方になる

もしよければ、今あなたが書いている小さなコンポーネントを一つ選んで、

  • props に type Props を付ける
  • useState にできる範囲で型注釈を付けてみる

ところから始めてみてください。

「型があるおかげでエディタが補完してくれる」「間違えたらその場で止めてくれる」
この“安心感”を一度味わうと、TypeScript からもう戻れなくなります。

タイトルとURLをコピーしました