問題
拡張されたjQueryをTypeScriptから使おうとしたら、コンパイル時このようなエラーが出た。
TS2339: Property 'request' does not exist on type 'JQueryStatic<HTMLElement>'.
この request
は下記のように追加された関数なので、当然jQueryの型定義ファイルには含まれていないため、このエラーが発生した。
$.fn.request = function (handler, option) {
...
return new Request($this, handler, options);
};
対策
型定義
型定義ファイルにこのrequest
関数を定義してやればよい。
interface JQueryStatic {
request(handler: string, options: any): any;
}
TypeScriptのinterface
は同じシグネチャの定義を複数記述すると、上書きや無視ではなく、ちゃんと合体してもらえる。おかげで、全て再定義せずに拡張することができる。
エラー文言から、$
はJQueryStatic
と認識されていることがわかるので、JQueryStatic
インタフェースを定義している。また、ここではとりあえずコンパイルが通るようにしたいだけなので、よくわからない型はany
とした。
型定義ファイルの配置と読み込み設定
型定義は任意のファイル名に拡張子「.d.ts」でOK。そして、tsconfig.jsonなどでコンパイラにこのファイルを読み込むように場所を教えてやる。
{
...
"compilerOptions": {
...
"baseUrl": "./",
"typeRoots": ["types", "node_modules/@types"]
}
}
baseUrl
で相対パスの起点となるディレクトリを設定し、typeRoots
に型定義ファイルが格納されているディレクトリを設定する。
ここでは、types
というディレクトリに自作の型定義ファイルを格納した。
これで、$.request(...)
とこの関数を使ってもちゃんとコンパイルするようになる。
トラブルシューティング
もし下記のようなエラーが発生した場合、型定義ファイルがコンパイル対象のファイルとして認識されてしまっていないか確認する。
Module build failed: Error: Typescript emitted no output for ...
私の場合、他のコンパイルすべき.tsファイルと同じディレクトリに型定義ファイル(.d.ts)を入れて、ディレクトリ中の.tsファイルをすべてコンパイルするように指定していたため、このエラーに遭遇した。