静的分析

静的分析はテストの一種で、実際にコードを実行したり自動テストを記述したりせずに、コードを自動的にチェックできます。VSCode などの IDE を使用する場合は、この種のテストをすでに見たことがあるでしょう。TypeScript によって実行される型チェックは一種の静的分析であり、エラーや警告の下に波線として表示されることがあります。

ESLint

ESLint は、コードベースで発生する可能性がある問題に関するフィードバックを提供するツールです。これらの問題はタイプセーフですが、それ自体はエラーや標準以外の動作です。ESLint では、コードベースでチェックされる多くのルール(「推奨」セットの多くを含む)を適用できます。

ESLint ルールの好例は、no-unsafe-finally ルールです。これにより、プログラムの制御フローを変更するステートメントを finally ブロック内で記述できなくなります。これは優れたルールです。この方法では、従うのが難しい可能性がある JavaScript の記述は一般的ではありません。ただし、これは健全なコードレビュー プロセスで検出できる必要があります。

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

そのため、ESLint は、健全なレビュー プロセス(およびコードベースの外観を定義するスタイルガイド)に代わるものではありません。デベロッパーがコードベースに導入しようとする非正統的なアプローチをすべて網羅しているわけではありません。Google のエンジニアリング プラクティス ガイドには、「シンプルに保つ」ための短いセクションがあります。

ESLint では、ルールに違反して、コードに「許可される」アノテーションを付けることができます。たとえば、前述のロジックを有効にするには、次のようにアノテーションを付けます。

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

ルール違反がたびたび発生する場合は、無効にすることを検討してください。これらのツールは特定の方法でコードを記述することが推奨されますが、チームが別の方法でコードを記述することに慣れていて、そのアプローチのリスクをすでに認識している可能性があります。

最後に、大規模なコードベースで静的分析ツールを有効にすると、通常はうまく機能していたコードに、有用でないノイズ(およびリファクタリングの多大な作業)が大量に発生する可能性があります。そのため、プロジェクトのライフサイクルの早い段階で有効にする方が簡単です。

ブラウザ サポート用の ESLint プラグイン

広くサポートされていない API やターゲット ブラウザのリストでサポートされていない API の使用を報告するプラグインを ESLint に追加できます。ユーザーが API を使用できない可能性がある場合、eslint-plugin-compat パッケージによって警告が表示されるため、デベロッパーを常に追跡する必要はありません。

静的分析の型チェック

JavaScript を習得するとき、新しいデベロッパーは通常、JavaScript が型指定が弱い言語であるという考え方に触れます。つまり、変数を 1 つの型として宣言してから、まったく異なるものに同じ場所を使用できます。これは Python や他のスクリプト言語に似ていますが、C/C++ や Rust などのコンパイル言語とは異なります。

この種の言語は始めるのに適しているかもしれません。そしておそらく、このシンプルさから JavaScript が広く普及しているのは間違いありませんが、一部のコードベースでは多くの場合、ややこしいエラーが発生する可能性があります。たとえば、string またはオブジェクト型が想定されている場所に number を渡すと、誤って型付けされた値がさまざまなライブラリに伝播され、最終的に TypeError を混乱させる可能性があります。

TypeScript

TypeScript は、JavaScript に型情報がない問題を解決する最も一般的なソリューションです。このコースでは幅広く使用します。このコースは TypeScript に関するコースではありませんが、静的分析が可能なため、ツールボックスの重要な部分となる可能性があります。

簡単な例として、string 名と number 年齢を受け取るコールバックを受け取るコードは次のようになります。

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

TypeScript を介して実行すると、または IDE でカーソルを合わせたときに、次のエラーが生成されます。

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
前の例のコードと IDE が、ポップアップにエラー メッセージとともに表示されます。
間違った型を渡したことを示す VSCode。

最終的には、TypeScript を使用する目的は、このようなエラー(経過時間は string ではなく number である必要がある)がプロジェクトに侵入するのを防ぐことです。この種のエラーは、他のタイプのテストでは検出が難しい場合があります。また、型システムは、テストが作成される前にフィードバックを提供できます。これにより、コードの最終的な実行時ではなく、ソフトウェアの開発時に型エラーに関する早期のフィードバックを提供することで、コードの記述プロセスが容易になります。

TypeScript を使用するうえで最も難しい点は、正しく設定することです。すべてのプロジェクトに tsconfig.json ファイルが必要です。このファイルは、主に tsc コマンドライン ツール自体で使用されますが、VSCode などの IDE、Vitest などの他の多くのビルドツールやツールでも読み取られます。このファイルには数百のオプションとフラグが含まれています。設定に役立つリソースは次のとおりです。

TypeScript の一般的なヒント

tsconfig.json ファイルで TypeScript をセットアップして使用する場合は、次の点に注意してください。

  • ソースファイルが実際に追加され、チェックされていることを確認してください。ファイルに「エラーがない」と不明な場合は、おそらくそのファイルがチェックされていないことが原因です。
  • .d.ts ファイル内に型やインターフェースを関数の記述時に暗黙的に記述するのではなく、明示的に記述することで、コードベースのテストが容易になります。関係するインターフェースが明確であれば、モックや「フェイク」バージョンのコードを作成しやすくなります。.

TypeScript は暗黙的のいずれかに

TypeScript の最も強力で意味のある構成オプションの 1 つが noImplicitAny フラグです。ただし、特に大規模なコードベースがある場合は特に、有効にすることが最も難しい場合がよくあります。(strict モードの場合、noImplicitAny フラグはデフォルトで有効になりますが、それ以外の場合は有効ではありません)。

このフラグを使用すると、この関数はエラーを返します。

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

読者としては、n が数値であることは明らかですが、TypeScript はこれを確信できません。VSCode を使用している場合、関数にカーソルを合わせると、次のように説明されます。

function fibonacci(n: any): any

この関数の呼び出し元は、number だけでなく、any 型の値(他の任意の型を許可する型)を渡すことができます。noImplicitAny フラグを有効にすると、特定の場所で誤ったデータ型を渡すコードに対して大規模なビジネス ロジック テストを記述しなくても、開発中にこの種のコードを保護できます。

この簡単な修正は、n 引数と fibonacci の戻り値の型の両方を number とすることです。

noImplicitAny フラグを設定しても、コードベースに any を明示的に書き込むことは禁止されません。any 型を受け入れるか返す関数を作成することもできます。すべての変数に型が与えられていることが保証されるだけです。