TypeScript に取り組む
この書籍を応援してください:購入するか、寄付する
(広告です。ブロックしないでください。)

2 なぜ TypeScript なのか?



すでに TypeScript を学習および使用することが確実な場合は、この章をスキップできます。

まだ迷っている場合は、この章は私のセールスポイントです。

2.1 TypeScript を使用する利点

2.1.1 より多くのエラーが静的に検出される(コードを実行せずに)

統合開発環境で TypeScript コードを編集している間、名前のスペルミス、関数の誤った呼び出しなどがある場合は警告が表示されます。

次の 2 行のコードを考えてみましょう。

function func() {}
funcc();

2 行目に対して、次の警告が表示されます。

Cannot find name 'funcc'. Did you mean 'func'?

別の例

const a = 0;
const b = true;
const result = a + b;

今回は、最後の行のエラーメッセージは次のようになります。

Operator '+' cannot be applied to types 'number' and 'boolean'.

2.1.2 パラメータをドキュメント化することは、いずれにせよ良い習慣である

関数とメソッドのパラメータをドキュメント化することは、多くの人がいずれにせよ行っていることです。

/**
 * @param {number} num - The number to convert to string
 * @returns {string} `num`, converted to string
 */
function toString(num) {
  return String(num);
}

{number}{string} を介して型を指定する必要はありませんが、英語での説明にもそれらが記載されています。

TypeScript の表記法を使用して型をドキュメント化すると、この情報の一貫性がチェックされるという追加の利点が得られます。

function toString(num: number): string {
  return String(num);
}

2.1.3 TypeScript は、追加のドキュメントレイヤーを提供する

JavaScript コードを TypeScript に移行するたびに、興味深い現象に気づきます。関数またはメソッドのパラメータに適した型を見つけるために、それが呼び出されている場所を確認する必要があります。つまり、静的型は、それ以外の場合は別の場所で検索する必要がある情報をローカルに提供してくれます。

そして実際、JavaScript コードベースよりも TypeScript コードベースを理解するのが簡単だと感じています。TypeScript は、追加のドキュメントレイヤーを提供します。

この追加のドキュメントは、チームで作業するときにも役立ちます。コードをどのように使用するかが明確になり、TypeScript は、何か間違ったことをしている場合に警告してくれることがよくあるからです。

2.1.4 JavaScript の型定義により、オートコンプリートが改善される

JavaScript コードに型定義がある場合、エディターはそれらを使用してオートコンプリートを改善できます。

TypeScript の構文を使用する代わりに、この章の冒頭で行ったように、JSDoc コメントを介してすべての型情報を提供する方法もあります。その場合、TypeScript はコードの一貫性をチェックし、型定義を生成することもできます。詳細については、TypeScript ハンドブックの「JavaScript ファイルの型チェック」の章を参照してください。

2.1.5 TypeScript により、リファクタリングが安全になる

リファクタリングは、多くの統合開発環境が提供する自動化されたコード変換です。

メソッドの名前変更は、リファクタリングの例です。プレーンな JavaScript でこれを行うのは難しい場合があります。同じ名前が異なるメソッドを参照している可能性があるためです。TypeScript には、メソッドと型がどのように接続されているかに関するより多くの情報があるため、そこでメソッドの名前変更をより安全に行うことができます。

2.1.6 TypeScript は、新しい機能を古いコードにコンパイルできる

TypeScript は、ECMAScript ステージ 4 の機能を迅速にサポートする傾向があります(これらの機能は、次の ECMAScript バージョンに含まれる予定です)。JavaScript にコンパイルする場合、コンパイラオプション --target を使用して、出力が互換性を持つ ECMAScript バージョンを指定できます。その後、互換性のない機能(後で導入されたもの)は、同等の互換性のあるコードにコンパイルされます。

古い ECMAScript バージョンのこのようなサポートには、TypeScript または静的型付けは必要ないことに注意してください。JavaScript コンパイラ Babel も同様のことを行いますが、JavaScript を JavaScript にコンパイルします。

2.2 TypeScript を使用する欠点

2.3 TypeScript の誤解

2.3.1 TypeScript コードは重い

TypeScript コードは非常に重くなる可能性があります。しかし、そうである必要はありません。たとえば、型推論により、多くの場合、型注釈をほとんど使用せずに済む場合があります。

function selectionSort(arr: number[]) { // (A)
  for (let i=0; i<arr.length; i++) {
    const minIndex = findMinIndex(arr, i);
    [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // swap
  }
}

function findMinIndex(arr: number[], startIndex: number) { // (B)
  let minValue = arr[startIndex];
  let minIndex = startIndex;
  for (let i=startIndex+1; i < arr.length; i++) {
    const curValue = arr[i];
    if (curValue < minValue) {
      minValue = curValue;
      minIndex = i;
    }
  }
  return minIndex;
}

const arr = [4, 2, 6, 3, 1, 5];
selectionSort(arr);
assert.deepEqual(
  arr, [1, 2, 3, 4, 5, 6]);

この TypeScript コードが JavaScript コードと異なる唯一の場所は、A 行と B 行です。

TypeScript が記述されるさまざまなスタイルがあります。

2.3.2 TypeScript は、JavaScript を C# または Java で置き換えようとする試みである

当初、TypeScript は独自の言語構成要素をいくつか発明しました(例:enum)。しかし、ECMAScript 6 以降は、ほとんどの場合、JavaScript の厳密なスーパーセットであり続けています。

私の印象では、TypeScript チームは JavaScript を気に入っており、それを「より良いもの」(たとえば、Dart の目標である)に置き換えたいとは考えていません。できるだけ多くの JavaScript コードを静的に型付けできるようにしたいと考えています。多くの新しい TypeScript 機能は、その願望によって推進されています。