第2章 TypeScriptへの移植の始め方とポイント
ここまで、JavaScriptからTypeScriptへ移行する具体的な手順を見てきました。しかし、実際のプロジェクトでは、これほど単純に進められるわけではありません。そこで、どういったところから手を付けていけばよいのか、いくつかのポイントを示しておきます。
大きな流れ
大きな流れをまずは示します。
- 必要ならフォルダ構造を整える
- tsconfig.jsonを作成する
- ファイル名を.js→.tsに変更する
- allowJs: true などの設定で、JSとTSの共存を許可する
- コンパイルエラーを一旦許容し、まずはJavaScriptファイルが出力される状態を目指す
- 重要なところから型を付けていく
tscを使ったコンパイルでは、エラーが出た場合でもJavaScriptのファイルは出力されます。そのため最初は、エラーが出ても気にしないで出力するとよいです。
すぐには型を付けられない場所は、とりあえずany型にしておくという方法も有効です。そして、プロジェクトにとって重要な箇所から段階的に型付けを進め、最終的に全体が型安全な状態になることを目指します。
重要なところがどこなのかは、プロジェクトによって異なるでしょう。しかしある程度の共通点はあるはずです。次からは、いくつかの指針を示します。
外部とやりとりする関数
まずは「外部とやりとりする関数」です。
- APIレスポンスを受け取る関数
- フロントエンドと通信するバックエンド関数
- ライブラリに提供するコールバック関数
こうした関数で外部との境界をきっちりと定めておけば、内部での変更は柔軟におこなえます。
入力と出力に型を付けた例を示します。
// APIから受け取るデータの型をきっちり定義
function fetchUser(id: number): Promise<User> {
// 実装
}
使用頻度の高い関数
次は「使用頻度の高い関数」です。
- プロジェクト全体で使われている関数
- 何回も呼び出される小さな処理
こうした関数は使用頻度が高いので、少し型を付けるだけで全体の堅牢さがアップしやすいです。
何度も呼び出される関数の例を示します。
function formatDate(date: Date, format: string): string {
// 実装
}
状態管理や設定データ
続いては「状態管理や設定データ」です。
- フレームワークやライブラリの状態データ
- アプリの設定オブジェクト
こうしたデータは、値の形が狂うと、アプリ全体が壊れるリスクがあります。そのため、誤って意図しない値が設定されるのを防ぐことが重要です。
設定の例を示します。
interface AppConfig {
apiUrl: string;
timeout: number;
}
const config: AppConfig = {
apiUrl: "https://example.com/api",
timeout: 5000,
};
複雑なオブジェクトをあつかう関数
次は「複雑なオブジェクトを扱う関数」です。
- ネストされたオブジェクト
- 配列とオブジェクトが混ざっているデータ
ネストが深いと、ミスに気づきにくくなるため型が有効です。このようなデータ構造は、ヒューマンエラーが発生しやすい箇所と言えます。
複雑なオブジェクトをあつかう関数の例を示します。
interface UserProfile {
name: string;
contact: {
email: string;
phone: string;
};
}
function displayUserProfile(profile: UserProfile): void {
console.log(profile.name, profile.contact.email);
}
第3章 まとめと次回予告
今回は、既存のJavaScriptのコードをTypeScriptに移行する方法について解説しました。次回は外部のパッケージの型定義の扱いなど、さらに実践的な内容を解説します。
- 第1回:【TypeScriptの基礎を学ぶ】JavaScriptと比較して起こりがちなミスを防ごう!
- 第2回:【TypeScriptの基礎を学ぶ】TypeScriptの型の付け方・あつかい方を解説
- 第3回:【TypeScriptの基礎を学ぶ】コードの表現力を高めよう!型ガードとジェネリクスによるデータ操作術
- 第4回:【TypeScriptの基礎を学ぶ】既存JavaScriptを着実にTypeScriptへ移行する実践ガイド
- 第5回:外部のパッケージやその他の情報(次回)
