TypeScript 3 と jQuery で sort() を使う方法

はじめに
今日は TypeScript 3 で jQuery を使用した際に sort() を使う方法を2つご紹介します。
- TypeScript
- 3.7.4
- jQuery
- 3.4.1
1. そのまま実装したらエラーになった
jQuery で sort をするためには下記のようなコードで実装できます。
<ol>
<li>B</li>
<li>D</li>
<li>C</li>
<li>A</li>
</ol>
<script src="js/main.js"></script>
$("ol").html(
$("li").sort(function(a, b) {
return ($(a).text() > $(b).text()) ? 1 : 0;
})
);
しかし、これをそのまま TypeScript のコードにしたところ、下記エラーが出てコンパイルができませんでした。
src\main.ts(2,11): error TS2339: Property 'sort' does not exist on type 'JQuery<HTMLElement>'.
src\main.ts(2,25): error TS7006: Parameter 'a' implicitly has an 'any' type.
src\main.ts(2,28): error TS7006: Parameter 'b' implicitly has an 'any' type.
下2行の変数 a, b については型指定がなくて怒られているので「a: HTMLElement」のようにすれば大丈夫でしょう。 問題は JQuery<HTMLElement> 型 に sort() 関数が定義されていないことです。 一番簡単そうなのは $("li") の箇所を any にキャストする方法です。例えば下記のように実装できます。 キャストをすれば簡単です。しかし、それでは TypeScript の良さを失っているような気がします。それを避ける方法として下記を考えました。 処理の内容は、まず $('li').get() で jQuery オブジェクトを配列に変換し、その配列をソートします。次に、ソート後の配列の各値を jQuery オブジェクトとして取得し、append() で並べ替えます。 これでキャストせずに実装できたのですが、最初のコードと比べるとちょっと煩雑で、今度は jQuery の良さが活かされていないように見えます。 今後 TypeScript の勉強を進めれば、もっとスマートな方法が分かるのかなとも思っています。その際は続報として投稿しようと思います。2. 手っ取り早い any キャスト
const $li:any = $('li');
$('ol').html(
$li.sort((a: HTMLElement, b: HTMLElement): number => {
return ($(a).text() > $(b).text()) ? 1 : 0;
})
);
3. キャストしないで対応
$('li').get().sort((a: HTMLElement, b: HTMLElement): number => {
return ($(a).text() > $(b).text()) ? 1 : 0;
}).forEach((value) => {
$('ol').append($(value));
});
4. おわりに