ReactとTypeScriptを組み合わせて開発していると、いろいろな選択肢や考え方が出てきます。
「どの型を使えばいいんだろう?」「書き方のベストプラクティスってあるの?」と悩むこともありますよね。
本記事では、React×TypeScriptの開発でわたしが普段意識しているポイントや、すぐに使えるTipsを紹介します!
TypeScriptの基本もおさらいしながら、実践的なテクニックをサクッと解説していきます。
開発のときに意識にしていること
🔹 関数の引数には型を指定し、戻り値はTypeScriptに任せる
関数の引数に型をつけることで、意図しない値が渡されるのを防ぐことができます。
ただ、戻り値の型はTypeScriptの型推論を活かしたほうがコードがスッキリすることが多いです。
function greet(name: string) {
return `Hello, ${name}!`;
}
戻り値の型を書かなくても、TypeScriptが自動でstring
と判断してくれます。
⚖️ 型のつけすぎは避ける
型をたくさんつけることで安全性が高まるのは確かですが、
全部に型をつけすぎると逆に可読性が落ちてしまうことも。
TypeScriptが推論できるところは任せるのがいいバランスだと思います。
const age = 30; // TypeScriptがnumber型と認識するのでOK
Reactコンポーネントで意識していること
📦 Propsの型定義はシンプルに
ReactコンポーネントのPropsを定義するときは、シンプルなオブジェクト型にするのがわかりやすいです。
function UserProfile({ name, age }: { name: string; age: number }) {
return (
<div>
<h1>{name}</h1>
<p>Age: {age}</p>
</div>
);
}
「どんなデータを渡せばいいのか」が一目でわかるので、チーム開発でも伝わりやすくなります。
🏗 ReactNode
を使って children
を型定義する
コンポーネントの children
には ReactNode
を指定するのが基本です。
import { ReactNode } from 'react';
function Container({ children }: { children: ReactNode }) {
return <div className="container">{children}</div>;
}
ReactNode
を使えば、文字列・数値・JSXなど幅広い要素を受け取れるので、
汎用性の高いコンポーネントを作るときに便利です。
便利な型の活用
🔄 ReturnType
と Awaited
を使って戻り値の型を取得する
関数の戻り値の型を手動で定義すると、修正時にズレが生じることがあります。
そこで ReturnType
を使うと、関数の戻り値をそのまま型として取得できます。
function getUser() {
return { name: "Alice", age: 25 };
}
type UserData = ReturnType<typeof getUser>;
非同期関数なら Awaited
も併用すると便利です。
async function fetchData() {
return { name: "Alice", age: 25 };
}
type UserData = Awaited<ReturnType<typeof fetchData>>;
こうすることで、関数の戻り値の型定義を一元管理できるので、
修正の際に一箇所だけ変更すれば済みます。
🔁 ComponentProps
を活用して型の再利用を簡単に!
ReactのComponentProps
を使うと、既存のコンポーネントのプロパティ型をそのまま再利用できます。
例えば、新しいコンポーネントを作る際に、わざわざ型を再定義しなくても既存の型を活用できるので、コードの重複を防ぎ、可読性とメンテナンス性を向上させることができます。
これにより、例えば入力フォームのカスタムコンポーネントを作成するときに、input
タグのすべてのプロパティをそのまま引き継ぎつつ、追加のカスタムプロパティを持たせることが可能です。
ComponentProps
を使うと、既存のHTMLタグやコンポーネントのPropsの型を簡単に再利用できます。
import React from 'react';
type CustomInputProps = React.ComponentProps<'input'> & {
label: string;
};
function CustomInput({ label, ...props }: CustomInputProps) {
return (
<label>
{label}
<input {...props} className="custom-input" />
</label>
);
}
export default function App() {
return <CustomInput label="Username" placeholder="Enter your username" />;
}
📌 as const
でリテラル型を固定する
as const
を使うと、オブジェクトや配列の値をリテラル型に固定できます。
const COLORS = {
primary: "#ff0000",
secondary: "#00ff00",
} as const;
type ColorKeys = keyof typeof COLORS;
これにより、COLORS.primary
は "#ff0000"
のように確定した型を持つようになります。
まとめ
React × TypeScript を使うときに意識していること!
✔ 関数の引数には型をつける!戻り値はTypeScriptにおまかせ!
✔ 型のつけすぎは避け、シンプルに!
✔ Propsの型定義は簡潔にまとめる!
✔ ReactNode
を使って children
を型定義する!
✔ ReturnType
& Awaited
で関数の戻り値を型として活用!
✔ ComponentProps
で型を再利用!
✔ as const
でリテラル型を固定!
これらをうまく活用することで、開発の効率がグッと上がります。
日々の開発で少しずつ試して、自分に合ったスタイルを見つけていきましょう!
それでは、よいエンジニアライフを! 🚀