Programmingフロントエンド開発者

TypeScriptでコールバック関数を正しく型指定するにはどうすればよいか、コンテキストと型エラーに関する留意点は何か?

Hintsage AIアシスタントで面接を突破

回答。

問題の歴史:JavaScriptではコールバック関数が広く使用されていますが、そのシグネチャはしばしば明確ではありません。TypeScriptでは、パラメーターと戻り値の型を明示的に指定する必要があり、そうでなければ型安全の穴が簡単に生じる可能性があります。

問題:コールバックの型指定が不正確または厳格でない場合、引数と結果の不明確な型が生じ、コンテキスト(this)の処理が難しくなり、コンパイラによる自動エラーチェックが破損し、リファクタリングが困難になります。

解決策:コールバック関数の型を明示的に定義し、渡されるパラメーターの型を指定し、オプションの引数と戻り値を適切に処理し、必要に応じてコンテキストの型も明示的に指定する必要があります。

コード例:

type Callback = (error: Error | null, result?: string) => void; function doAsyncWork(data: string, cb: Callback): void { setTimeout(() => { if (data === '') cb(new Error('Empty string')); else cb(null, data.toUpperCase()); }, 100); }

主な特徴:

  • コールバックのすべてのパラメーターの型を必ず指定してください。
  • 戻り値の型も、たとえそれがvoidであっても記述してください。
  • 必要に応じてthisの型を明示的に指定してください(例えば、コンテキスト付きの関数を通じて)。

落とし穴のある質問。

コールバックの戻り値型を指定しないとどうなるか?

TypeScriptは任意の戻り値型(例:undefined、void、Promise)を受け入れるため、非同期チェーンや「デフォルト」値の返却時にサプライズを引き起こす可能性があります。

type BadCallback = (data: string) => any; // 任意の結果、制御の欠如

コールバックをFunctionや(...args: any[]) => anyと書くことはできるか?

できません。これはすべての型保護を取り除き、パラメーターの数、型、および戻り値の型に関する情報が失われます。このアプローチは、TypeScriptを完全に放棄するよりも費用がかかります。

thisのコンテキストを持つ関数をどのように型指定するか?

関数のシグネチャでthisを最初のパラメーターとして使用するか、bindを使用してキャストしてください。たとえば:

interface ClickCallback { (this: HTMLElement, event: MouseEvent): void; } const handler: ClickCallback = function (event) { this.textContent = 'ok'; };

タイプエラーとアンチパターン

  • 型指定されていないコールバック(anyまたはFunction)
  • 関数シグネチャに戻り値の型がない
  • thisの型不一致がランタイムエラーを引き起こす

実生活の例

ネガティブケース

プロジェクトでコールバックが(...args: any[]) => anyとして宣言されていました。ビジネスロジックの更新に伴い、シグネチャが変更され、コールバックは必要な引数を渡さなくなり、バグは本番環境でのみ明らかになりました。

利点:

  • サードパーティのコードに対するコンパイルと接続が簡単になります。

欠点:

  • 型レベルでの保護が全くありません。
  • 更新が難しくなります。

ポジティブケース

厳密な型を導入しました:コールバックのインターフェースを記述し、thisの型と戻り値の型を明示的に指定しました。コンパイラはデプロイ前にエラーを捕捉し、リファクタリングとバグ修正のサポートが簡素化されました。

利点:

  • 型の安全性
  • コンパイル時のシグネチャ変更のチェック

欠点:

  • 型指定が少し複雑になり、ボイラープレートの量が増加しました。