🛠️
それなりの規模の JavaScript project で TypeScript 変換 (ts-migrate) を試してみる
What
- airbnb/ts-migrate [1] を試したいが、ある程度規模がある JavaScript の project を自分で作るのは面倒。
- なので、適当に GitHub から MIT License の project を folk してきて、それを実験に使わせてもらう。
GitHub 検索
GitHub Advanced search で適当に探す。
clone 系の repository とか結構な規模があって、実験にちょうどよさそう。
package.json など見て、そこそこ依存 package の多いものを探す。
TL;DR
Procedure
Summary
実 Project でやるなら、以下の順番でやるといいと思う(今回は eslint, prettier は省いた)
- eslint, prettier で error がない状態にする
- 修正できない eslint errors は、eslint-interactive [2] で一括 ignore する
- facebook/jscodeshift [3] + 5to6/5to6-codemod [4] で old syntax を migrate
- ts-migrate
Details
jscodeshift + 5to6-codemod で old syntax を migrate
事前に commonjs require/exports -> ES6 import/export に変えておいた方が type error が少なくなりそうなので。
# install
yarn add -D jscodeshift 5to6-codemod
# exec
node node_modules/.bin/jscodeshift -t node_modules/5to6-codemod/transforms/cjs.js src
node node_modules/.bin/jscodeshift -t node_modules/5to6-codemod/transforms/exports.js src
# uninstall
# 使い終わったら残しておく理由もない・CI での install が重くなるので消す。
yarn remove jscodeshift 5to6-codemod
ts-migrate
# install
yarn add -D ts-migrate typescript
# create tsconfig
yarn ts-migrate init .
# js/jsx -> ts/tsx
yarn ts-migrate rename .
# ts-migrate が付与する any に別 type 名を付けるためのファイルを作る
# 「人間が意図があって付けた any」と「ts-migrate が付けた any」を見分けられた方がよいため
vi src/tsfixme.d.ts
yarn ts-migrate migrate --aliases tsfixme .
src/tsfixme.d.ts
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type $TSFixMe = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type $TSFixMeFunction = (...args: any[]) => any;
ts-migrate の継続運用
- 以下のような時、ts-migrate を再実行する。一括で suppress comment の追加/削除ができる。
- tsconfig.json を更新して、新しい error が出るようになった。
- @types を install して、error が出なくなった。
yarn ts-migrate reignore .
-
注意
-
ts-migrate migrate
直後、何もしてない状態でも diff が出た。 - なので、何もなくても
ts-migrate reignore
は 1 度実行 & commit しておいた方がよさそう。
-
他
- function -> arrow の変換も jscodeshift でできそうだが、継続的に禁止すると思うので eslint の prefer-arrow-functions の autofix を利用するとよいだろう。
まとめ
- 拡張子変えて明示的 any だらけにするだけなので、正直「既存は js のまま、新規は ts、徐々に直してく」でもよくね?と思っていた。
- が、こんなに簡単・安定して変換できるなら、fool proof のためにも一括変換しておく方がよさそう。
- 型なしコードを滅ぼしていきましょう。
参考記事
- JS から TS への移行ツール、ts-migrate を試してみた - Qiita
- "Automatically Migrating to TypeScript with ts-migrate" - Evan Shaw (nz.js(con); 2021) - YouTube
-
JS -> TS に一括変換してれるツール。airbnb 製。 ↩︎
-
JS/TS を一括編集してれるツール。transform の内容は自分で実装 or OSS を利用する。Facebook 製。moment.js の置換などもできる。date-fns 派だけど、moment 互換がこんな形で活きてるとは。(ref. jscodeshift で Moment.js を Day.js に一括置換した話 - ミツモア Tech blog) ↩︎
-
jscodeshift 用 transformer。主に commonjs require/exports -> ES6 import/export の変換ができる。 ↩︎
Discussion