第6章 冒頭のミスをTypeScriptで防いでみよう
それでは、今回の記事の冒頭で示した「起こりがちなミス」をTypeScriptで解決しましょう。
その1 プロパティ名ミス
type
でUser
という型を作り、saveUser
関数の引数user
に型を付けます。型はuser: User
のように書きます。
type User = { name: string; email: string; }; // ユーザー情報の保存 function saveUser(user: User) { console.log("Name:", user.name); console.log("Email:", user.email); } // 呼び出し側 saveUser({ neme: "佐藤太郎", // タイプミス email: "tarou@example.com" });
VSCodeで、この型を加えた段階でneme
に赤線が現れてエラーが検出されます。
次に、npx tsc
で型チェックをしてみましょう。
npx tsc main.ts
この方法では、変換したJavaScriptが出力されます。型チェックだけをおこないたいときは、--noEmit
を付けます。
npx tsc main.ts --noEmit
いずれの場合でも、次のようにエラーが表示されます。ミスはどこだろうと、血眼になってコードを確認する必要がなくなります。
main.ts:14:5 - error TS2353: Object literal may only specify known properties, and 'neme' does not exist in type 'User'. 14 neme: "佐藤太郎", // タイプミス ~~~~ Found 1 error in main.ts:14
その2 型ミス
Config
という型を作り、プロパティの型を確認するようにしましょう。setup
関数の引数config
に型を付けます。型はconfig: Config
のように書きます。
type Config = { retry: number; timeout: number; }; // 設定 function setup(config: Config) { console.log("Config:", config); } // 呼び出し側 setup({ retry: "3", // numberなのに、stringで渡した timeout: 5000 });
VSCodeで、この型を加えた段階でsetup
の引数に書いたretry
に赤線が現れてエラーが検出されます。
次に、npx tsc
で型チェックをしてみましょう。エラーがあるのは分かっているので、JavaScriptのファイルは出力せずに、型チェックだけをおこないます。
npx tsc main.ts --noEmit
次のようにエラーが表示されます。起こりうるエラーを未然に防ぐことができます。
main.ts:13:5 - error TS2322: Type 'string' is not assignable to type 'number'. 13 retry: "3", // numberなのに、stringで渡した ~~~~~ main.ts:2:3 2 retry: number; ~~~~~ The expected type comes from property 'retry' which is declared here on type 'Config' Found 1 error in main.ts:13
その3 プロパティを間違えて扱う
今度は、少し難しいケースです。TypeScriptの型の書き方には、「あってもなくても構わないプロパティ」を指定する方法があります。age?: number
のように?
を付ける記法です。まずは、この方法で型を指定します。
type UserProfile = { name: string; age?: number; // Optional }; // プロフィールの表示 function displayProfile(user: UserProfile) { console.log("Name:", user.name); console.log("Age:", user.age.toFixed(0)); } // 呼び出し側 displayProfile({ name: "太郎" // ageは未設定 });
このコードを書くと、VSCodeでdisplayProfile
関数のuser.age
の部分に赤線が引かれます。
マウスカーソルを重ねてポップアップすると'user.age' is possibly 'undefined'.
というメッセージが表示されます。age
プロパティの値がundefined
になる可能性があるというエラーです。
このコードを、tsconfig.json
を作っていない状態で、そのままtsc
で型チェックします。この場合、実はエラーが出ません。
npx tsc main.ts --noEmit
tsc
での型チェックは、デフォルトの状態では、今回のケースのエラーを検出しません。検出するためには、strictNullChecks
をtrue
にする必要があります。
設定を変更するには、tsconfig.json
を作成して設定を変更するか、実行時引数に値を追加します。今回は後者の方法を利用します。
npx tsc main.ts --noEmit --strictNullChecks true
この方法で実行すると、次のようにエラーが出力されます。
main.ts:9:25 - error TS18048: 'user.age' is possibly 'undefined'. 9 console.log("Age:", user.age.toFixed(0)); ~~~~~~~~ Found 1 error in main.ts:9
エラーが検出されたので、コードを修正しましょう。user.age.toFixed(0)
の部分をuser.age?.toFixed(0)
に変更します。
.
を?.
に変更したことで、age
がundefined
の場合はtoFixed
を実行しないようになりました。
type UserProfile = { name: string; age?: number; // Optional }; // プロフィールの表示 function displayProfile(user: UserProfile) { console.log("Name:", user.name); console.log("Age:", user.age?.toFixed(0)); } // 呼び出し側 displayProfile({ name: "太郎" // ageは未設定 });
このコードを出力して、Node.jsで実行してみましょう。出力するコードはes2024
準拠にします。
npx tsc main.ts --strictNullChecks true --target es2024 node main.js
Name: 太郎 Age: undefined
エラーが出ずに実行できました。TypeScriptでは、このようにしてエラーを防げます。
まとめと次回予告
今回は、TypeScriptに軽く入門してみました。次回からはさらに踏み込んで、TypeScriptの仕様に触れていきます。