こんにちは、かつコーチです。
前回は、非nullアサーション(!)を使うべき場面・避けるべき場面について解説しました。
型注釈やジェネリクスを覚えてきても、実際にコードを書いていると必ずぶつかるのが「赤い波線」と「見慣れない英語のエラーメッセージ」です。
今回は、TypeScriptを書いていて特によく出会うエラーを取り上げて、その読み方と対処法を整理していきます。
エラーメッセージは怖いものではなく、TypeScriptが「ここが危ないですよ」と教えてくれているヒントだと捉えられるようになると、学習が一気に楽になります。
TypeScriptのエラーメッセージの基本構造
エラーコード(TSxxxx)に注目する
TypeScriptのエラーメッセージには、必ずTS2322のような「エラーコード」が付いています。
Type 'string' is not assignable to type 'number'. (2322)
このコード番号は、TypeScriptの種類ごとに固定で振られているので、検索するときの手がかりになります。
私は最初、日本語の意訳だけで理解しようとして遠回りしていましたが、コード番号ごと検索するとピンポイントで解説記事にたどり着けることに気づいてから、調べる速度が一気に上がりました。
メッセージは「どこが」「なぜ」ダメなのかを教えてくれる
エラーメッセージは基本的に、次の2つの情報で構成されています。
- どの型とどの型がぶつかっているか
- なぜそれが許されないのか
いきなり全文を訳そうとせず、「型Aを型Bに入れようとして拒否された」という構造だけをまず掴むのがコツです。
エラー1:Type ‘○○’ is not assignable to type ‘△△’
どんな場面で出るか
一番よく見るのが、この「型が代入できません」エラーです。
let age: number;
age = "20"; // エラー
❌ Before:型が合わないまま代入しようとする
function calculateTax(price: number): number {
return price * 1.1;
}
const inputValue = "1000"; // フォームからの入力は文字列で来ることが多い
calculateTax(inputValue);
// Argument of type 'string' is not assignable to parameter of type 'number'.
フォームの入力値は基本的に文字列として渡ってくるため、このパターンは実務でも頻出です。
✅ After:明示的に型を変換してから渡す
function calculateTax(price: number): number {
return price * 1.1;
}
const inputValue = "1000";
calculateTax(Number(inputValue)); // 数値に変換してから渡す
エラーメッセージにstringとnumberという単語が出てきたら、「どちらかを変換すれば解決する」というパターンだと覚えておくと、対処が早くなります。
エラー2:Object is possibly ‘undefined’(またはnull)
つまずきやすいポイント:配列やオプショナルなプロパティ
私が実務で一番よく遭遇したのが、このエラーです。
type User = {
name: string;
email?: string; // オプショナルなプロパティ
};
function showEmail(user: User) {
console.log(user.email.length); // エラー
}
email?のように?が付いているプロパティは「存在するかもしれないし、しないかもしれない」という型になるため、TypeScriptは.lengthを呼び出す前に「本当に存在するか確認してください」と警告します。
私は初めてこのエラーに出会ったとき、「さっき型を定義したばかりなのに、なぜ怒られるんだ」と数分間画面を睨んでいました。
原因は単純で、emailをオプショナルにした時点で「ないかもしれない値」として扱われるようになっていたからです。
❌ Before:存在チェックをせずにプロパティへアクセスする
function showEmail(user: User) {
console.log(user.email.length);
// Object is possibly 'undefined'.
}
✅ After:条件分岐やオプショナルチェイニングで存在を確認する
function showEmail(user: User) {
if (user.email) {
console.log(user.email.length);
} else {
console.log("メールアドレスは未登録です");
}
}
// もしくはオプショナルチェイニングで簡潔に書く
function showEmailLength(user: User) {
console.log(user.email?.length ?? "未登録");
}
if文で存在を確認するか、?.(オプショナルチェイニング)と??(Null合体演算子)を組み合わせることで、安全に値へアクセスできます。
エラー3:Property ‘○○’ does not exist on type ‘△△’
タイプミスや型定義漏れのサイン
このエラーは、存在しないプロパティにアクセスしようとしたときに出ます。
type Product = {
name: string;
price: number;
};
const product: Product = { name: "ノート", price: 300 };
console.log(product.pirce); // タイプミス(price → pirce)
// Property 'pirce' does not exist on type 'Product'.
このエラーの原因は、大きく分けて2パターンあります。
- 単純なタイプミス(
priceをpirceと書いてしまった等) - 型定義そのものにプロパティが足りていない
まず自分のコードでタイプミスをしていないか確認し、それでも解決しない場合は型定義の方を見直すという順番で調べると、無駄な時間を減らせます。
型定義に足りないプロパティがある場合
APIレスポンスの型を手作業で定義しているときに、このパターンによく出会います。
// APIから実際は discount フィールドも返ってくるのに、型定義に書き忘れていた
type ApiProduct = {
name: string;
price: number;
};
function showDiscount(product: ApiProduct) {
console.log(product.discount); // エラー
}
この場合の対処は、型定義側に不足しているプロパティを追加することです。
type ApiProduct = {
name: string;
price: number;
discount: number; // 不足していたプロパティを追加
};
「コードが間違っている」のではなく「型定義が実態に追いついていない」だけというケースは意外と多いので、エラーが出たら疑う先を両方持っておくと調査が早くなります。
エラー4:Argument of type ‘○○’ is not assignable to parameter of type ‘△△’
関数の引数まわりで頻出するパターン
これは先ほどの「代入できません」エラーの、関数の引数版です。
type Status = "pending" | "success" | "error";
function updateStatus(status: Status) {
console.log(`ステータス: ${status}`);
}
updateStatus("done"); // エラー
// Argument of type '"done"' is not assignable to parameter of type 'Status'.
ユニオン型("pending" | "success" | "error")で許可されている値以外を渡したときに出るエラーです。
エラーメッセージの中に、実際に許可されている値の候補が表示されることも多いので、まずはメッセージ内の型の一覧をよく読むことが解決の近道になります。
updateStatus("success"); // 許可された値なのでOK
エラー調査を効率化するコツ
エディタのホバー機能を使う
エラーが出た変数や関数にマウスを乗せると、VS Codeなどのエディタは「今その値がどんな型として推論されているか」を表示してくれます。
エラーメッセージの型名だけを見て悩むより、まずホバーして実際の型を確認する方が原因特定が早いことがほとんどです。
エラーコードで検索する
先述の通り、TS2322のようなコードで検索すると、TypeScript公式ドキュメントや解説記事がヒットしやすくなります。
日本語のエラー文をそのままコピーして検索するより、コード番号や英語のキーワードで検索した方が情報量の多い記事に当たりやすいので、ぜひ試してみてください。
まとめ
この記事のポイント
- TypeScriptのエラーには
TSxxxxというコードが付いており、検索の手がかりになる - 「型Aを型Bに代入できません」は、どちらかの型を変換すれば解決することが多い
possibly 'undefined'は、存在チェックやオプショナルチェイニングで対処する- プロパティが存在しないエラーは「タイプミス」か「型定義の不足」のどちらかを疑う
- エディタのホバー機能とエラーコード検索を組み合わせると調査が早くなる
次に読むべき記事
エラーの読み方が分かってきたら、次はエラーそのものを未然に防ぐための設定を見ていきましょう。
→ 次の記事:strictモードとは?tsconfig.jsonの主要オプション解説
