TypeScriptの使用
TypeScriptは、JavaScriptコードベースに型定義を追加する一般的な方法です。TypeScriptはデフォルトでJSXをサポートしており、@types/reactと@types/react-domをプロジェクトに追加することで、完全なReact Webサポートを得ることができます。
インストール
すべての本番環境対応のReactフレームワークは、TypeScriptの使用をサポートしています。インストールについては、各フレームワーク固有のガイドに従ってください:
既存のReactプロジェクトにTypeScriptを追加する
Reactの型定義の最新バージョンをインストールするには:
npm install --save-dev @types/react @types/react-dom以下のコンパイラオプションをtsconfig.jsonで設定する必要があります:
domをlibに含める必要があります(注:libオプションが指定されていない場合、domはデフォルトで含まれます)。- jsxは有効なオプションのいずれかに設定する必要があります。ほとんどのアプリケーションでは
preserveで十分です。 ライブラリを公開する場合は、jsxのドキュメントを参照して、どの値を選択するかを確認してください。
ReactコンポーネントでのTypeScript
注記
JSXを含むすべてのファイルは.tsxファイル拡張子を使用する必要があります。これはTypeScript固有の拡張子で、このファイルにJSXが含まれていることをTypeScriptに伝えます。
ReactでTypeScriptを書くことは、ReactでJavaScriptを書くことと非常に似ています。コンポーネントを扱う際の主な違いは、コンポーネントのpropsに型を提供できることです。これらの型は、正確性のチェックやエディタでのインラインドキュメントの提供に使用できます。
MyButtonコンポーネントをクイックスタートガイドから取り上げ、ボタンのtitleを記述する型を追加できます:
注記
これらのサンドボックスはTypeScriptコードを処理できますが、型チェッカーは実行しません。つまり、TypeScriptサンドボックスを修正して学習することはできますが、型エラーや警告は表示されません。型チェックを行うには、TypeScript Playgroundを使用するか、より機能豊富なオンラインサンドボックスを使用してください。
このインライン構文は、コンポーネントに型を提供する最も簡単な方法ですが、記述するフィールドがいくつかあると扱いにくくなる可能性があります。代わりに、interfaceまたはtypeを使用してコンポーネントのpropsを記述できます:
コンポーネントのpropsを記述する型は、必要に応じてシンプルにも複雑にもできますが、通常はtypeまたはinterfaceで記述されたオブジェクト型であるべきです。TypeScriptがオブジェクトをどのように記述するかについては、オブジェクト型で学ぶことができます。また、いくつかの異なる型のいずれかになり得るpropを記述するためにユニオン型を使用することや、より高度なユースケースについては型から型を作成するガイドも参考になるでしょう。
フックの例
@types/reactの型定義には組み込みのフックの型が含まれているため、追加の設定なしでコンポーネント内で使用できます。これらはコンポーネント内で記述するコードを考慮して構築されているため、多くの場合型推論が行われ、理想的には型を提供する細かい作業を扱う必要はありません。
ただし、フックに型を提供する方法の例をいくつか見てみましょう。
useState
useStateフックは、初期状態として渡された値を再利用して、値の型を決定します。例えば:
これにより、enabledにboolean型が割り当てられ、setEnabledはboolean引数、またはbooleanを返す関数を受け入れる関数になります。状態に対して明示的に型を提供したい場合は、useState呼び出しに型引数を指定することで行えます:
このケースではあまり有用ではありませんが、型を提供したくなる一般的なケースはユニオン型を持つ場合です。例えば、ここでのstatusはいくつかの異なる文字列のいずれかになります:
または、状態構造化の原則で推奨されているように、関連する状態をオブジェクトとしてグループ化し、オブジェクト型を通じて異なる可能性を記述することもできます:
useReducer
useReducerフックは、リデューサー関数と初期状態を受け取るより複雑なフックです。リデューサー関数の型は初期状態から推論されます。useReducer呼び出しに型引数を指定して状態の型を提供することもできますが、多くの場合、初期状態に型を設定する方が良いでしょう:
いくつかの重要な箇所でTypeScriptを使用しています:
interface Stateは、リデューサーの状態の形状を記述します。type CounterActionは、リデューサーにディスパッチできるさまざまなアクションを記述します。const initialState: Stateは初期状態の型を提供し、またデフォルトでuseReducerによって使用される型でもあります。stateReducer(state: State, action: CounterAction): Stateは、リデューサー関数の引数と戻り値の型を設定します。
より明示的な代替方法として、initialStateに型を設定する代わりに、useReducerに型引数を提供することができます:
useContext
このuseContext フックは、コンポーネントツリーの下にデータを渡すための手法で、コンポーネント間で props を渡す必要がありません。プロバイダーコンポーネントを作成し、多くの場合、子コンポーネントでその値を消費するためのフックを作成することで使用されます。
コンテキストによって提供される値の型は、createContext呼び出しに渡された値から推論されます:
この手法は、意味のあるデフォルト値がある場合に機能しますが、時にはデフォルト値がない場合もあり、そのような場合にはnullがデフォルト値として妥当に感じられることがあります。しかし、型システムがコードを理解できるようにするには、ContextShape | null を createContextに明示的に設定する必要があります。
これにより、コンテキストの利用者側で型から| nullを排除する必要が生じます。私たちの推奨は、フックがその存在を実行時にチェックし、存在しない場合にエラーをスローすることです:
useMemo
注記
React Compiler は値と関数を自動的にメモ化するため、手動での useMemo呼び出しの必要性が減少します。メモ化を自動的に処理するためにコンパイラを使用できます。
このuseMemoフックは、関数呼び出しからメモ化された値を作成/再アクセスし、2番目のパラメータとして渡された依存関係が変更された場合にのみ関数を再実行します。フック呼び出しの結果は、最初のパラメータの関数からの戻り値から推論されます。フックに型引数を提供することで、より明示的にすることができます。
useCallback
注記
React Compiler は値と関数を自動的にメモ化するため、手動での useCallback呼び出しの必要性が減少します。メモ化を自動的に処理するためにコンパイラを使用できます。
このuseCallbackは、2番目のパラメータに渡された依存関係が同じである限り、関数への安定した参照を提供します。useMemoと同様に、関数の型は最初のパラメータの関数の戻り値から推論され、フックに型引数を提供することでより明示的にすることができます。
TypeScript の厳格モードで作業する場合、useCallbackではコールバックのパラメータに型を追加する必要があります。これは、コールバックの型が関数の戻り値から推論されるためであり、パラメータがないと型を完全に理解できないからです。
コードスタイルの好みに応じて、React の型から*EventHandler関数を使用して、コールバックを定義するのと同時にイベントハンドラーの型を提供することができます:
便利な型
React と TypeScript の連携に慣れてきたら、@types/reactパッケージから提供される非常に広範な型のセットを読む価値があります。それらはDefinitelyTyped の React フォルダで見つけることができます。ここでは、より一般的ないくつかの型について説明します。
DOM イベントの型付け
React で DOM イベントを扱う場合、イベントの型は多くの場合、イベントハンドラから推論できます。しかし、イベントハンドラに渡す関数を抽出したい場合は、イベントの型を明示的に設定する必要があります。
React の型定義では多くの種類のイベントが提供されています。完全なリストは、こちらで確認できます。これはDOM で最も一般的なイベントに基づいています。
探している型を特定するには、まず使用しているイベントハンドラのホバー情報を確認すると、イベントの型が表示されます。
このリストに含まれていないイベントを使用する必要がある場合は、すべてのイベントの基本型であるReact.SyntheticEvent 型を使用できます。
Children の型付け
コンポーネントの children を記述する一般的な方法は2つあります。1つ目は、JSX で children として渡すことができるすべての可能な型のユニオン型であるReact.ReactNode 型を使用する方法です:
これは children の非常に広い定義です。2つ目は、文字列や数値などの JavaScript プリミティブではなく、JSX 要素のみを指すReact.ReactElement 型を使用する方法です:
注意点として、TypeScript を使用して children が特定の種類の JSX 要素であると記述することはできません。つまり、型システムを使用して、<li>要素のみを children として受け入れるコンポーネントを記述することはできません。
型チェッカーを使用したReact.ReactNode と React.ReactElement の両方の例は、この TypeScript プレイグラウンドで確認できます。
スタイルプロパティの型付け
React でインラインスタイルを使用する場合、React.CSSProperties を使用して styleプロパティに渡されるオブジェクトを記述できます。この型はすべての可能な CSS プロパティのユニオン型であり、styleプロパティに有効な CSS プロパティを渡していることを確認し、エディタでオートコンプリートを得るのに適した方法です。
さらなる学習
ドキュメントの各 API ページには、TypeScript でそれらを使用する方法についてのより詳細なドキュメントが含まれている場合があります。
以下のリソースをお勧めします:
- TypeScriptハンドブックはTypeScriptの公式ドキュメントで、主要な言語機能のほとんどをカバーしています。
- TypeScriptリリースノートでは、新機能について詳しく解説しています。
- React TypeScript チートシートは、ReactとTypeScriptを併用するためのコミュニティ管理のチートシートで、多くの有用なエッジケースをカバーし、このドキュメントよりも広範な情報を提供しています。
- TypeScriptコミュニティDiscordは、TypeScriptやReactに関する質問をしたり、助けを得たりするのに最適な場所です。
