はじめに
この記事は、TypeScriptのコンパイル時にエラーが出てしまった人に向けて、その解決策の一つとして紹介します。触りたてであやふやな人でもわかるように書いていきます。
TypeScriptとは
TypeScriptは、JavaScriptの代替となるべくマイクロソフトによって開発されたオープンソースのプログラミング言語です。TypeScriptの最大の特徴は、静的型付けが導入されていることです。JavaScriptは動的型付けの言語で、変数にどのようなデータ型が入るかを明示的に指定しませんが、TypeScriptでは型を指定することができます。これによって、コードを書いている時点でエラーを防ぐことができ、安全性、可読性の向上の面で使われています。
TypeScriptの環境構築については、こちらの@ochiochi様の
TypeScriptチュートリアル -環境構築編-に詳しく書かれています。
コンパイルエラーの例
TypeScriptのコンパイルエラーは、主に型に関するエラーや構文に関連するものが多いです。いくつかの典型的なコンパイルエラーの例を挙げて、それぞれのエラーがなぜ発生するのかを説明します。
1.型の不一致エラー
let age: number = "30";
// エラー: 型 'string' を型 'number' に割り当てることはできません
ageという変数はnumber型として宣言されていますが、"30"という文字列を代入しようとしています。このように、型が一致しない場合はコンパイルエラーが発生します。
let age: number = 30;
こちらが、修正されたコードとなります。
2.プロパティの存在確認エラー
interface Person {
name: string;
age: number;
}
let person: Person = { name: "John" };
// エラー: プロパティ 'age' は型 'Person' に必須ですが、'{ name: string; }' に存在しません
Personインターフェースにはnameとageの両方が必須のプロパティとして定義されています。しかし、personオブジェクトにはnameプロパティしか含まれていないため、ageが欠けていることでエラーが発生しています。
interface Person {
name: string;
age: number;
}
let person: Person = { name: "John",age: 30};
こちらが、修正されたコードとなります。
3.型推論に基づくエラー
let count = 10; // TypeScriptはこれをnumberと推論
count = "twenty"; // エラー: 型 'string' を型 'number' に割り当てることはできません
TypeScriptはcount変数をnumber型として推論しています。しかし、その後に"twenty"という文字列を代入しようとしたため、型の不一致によるエラーが発生します。
let count = 10;
count = 20;
こちらが、修正されたコードとなります。
4.数のパラメータ型エラー
function greet(name: string): void {
console.log(`Hello, ${name}!`);
}
greet(42);
// エラー: 型 'number' の引数を型 'string' のパラメータに割り当てることはできません
greet関数の引数nameはstring型として定義されていますが、42というnumber型の値を渡しているためエラーが発生しています。
function greet(name: string): void {
console.log(`Hello, ${name}!`);
}
greet("John");
こちらが、修正されたコードとなります。
5. 未定義のプロパティへのアクセス
let user: { name: string; age?: number } = { name: "Alice" };
console.log(user.age.toFixed(2));
// エラー: 型 'undefined' かもしれないオブジェクトのプロパティ 'toFixed' を呼び出すことはできません
ageはオプショナルプロパティ(age?: number)として定義されています。そのため、ageがundefinedの可能性があり、その状態でtoFixedメソッドを呼び出そうとするとエラーになります。TypeScriptはこのような潜在的なバグを防ぐため、オプショナルプロパティには適切な存在確認が必要です。
let user: { name: string; age?: number } = { name: "Alice" };
if (user.age !== undefined) {
console.log(user.age.toFixed(2));
}
こちらが、修正されたコードとなります。
6.関数の戻り値型エラー
function getNumber(): number {
return "Hello"; // エラー: 型 'string' を型 'number' に割り当てることはできません
}
getNumber関数はnumber型を返すべきと宣言されていますが、実際には"Hello"という文字列を返そうとしています。この型の不一致によりエラーが発生します。
function getNumber(): string {
return "Hello";
}
こちらが、修正されたコードとなります。
7. クラスのプロパティ初期化エラー
class Car {
model: string;
year: number = 2020;
}
let myCar = new Car();
console.log(myCar.model); // エラー: 'model' の値は使用される前に割り当てられていません。
TypeScriptはクラスのプロパティが必ず初期化されることを期待しますが、modelプロパティは初期化されていないためエラーが発生しています。これを解決するには、プロパティに初期値を与えるか、コンストラクタ内で初期化する必要があります。
class Car {
model: string = "Unknown";
year: number = 2020;
}
let myCar = new Car();
console.log(myCar.model);
またはコンストラクタ内で、
class Car {
model: string;
year: number = 2020;
constructor(model: string) {
this.model = model;
}
}
let myCar = new Car();
console.log(myCar.model);
することによって、修正することができます。
8. 範囲外の配列アクセスエラー(厳密なチェックモード時)
let numbers: number[] = [1, 2, 3];
console.log(numbers[5].toFixed(2));
// エラー: 'undefined' かもしれないオブジェクトのプロパティ 'toFixed' を呼び出すことはできません
配列のインデックス5には要素が存在しないため、numbers[5]はundefinedです。undefinedに対してtoFixedを呼び出そうとするとエラーになります。範囲外のアクセスは実行時エラーを引き起こす可能性があるため、TypeScriptはこれを防ぎます。
let numbers: number[] = [1, 2, 3];
console.log(numbers[5]?.toFixed(2));
TypeScriptのオプショナルチェイニング(?.)を使って、存在しない場合に自動的に undefined を返すやり方を使用し、修正することができます。
まとめ
TypeScriptのコンパイル時に発生するであろうエラーとその対処法について、出来るだけたくさん書きました。私自身も、全然できない初学者であるため、間違っている部分やカバーしきれないエラーがあるかもしれません。これらがあなたの助けになれば幸いです。良いTypeScriptライフをお過ごしください!