🛠️

それなりの規模の JavaScript project で TypeScript 変換 (ts-migrate) を試してみる

2022/10/10に公開

What

  • airbnb/ts-migrate [1] を試したいが、ある程度規模がある JavaScript の project を自分で作るのは面倒。
  • なので、適当に GitHub から MIT License の project を folk してきて、それを実験に使わせてもらう。

GitHub 検索

GitHub Advanced search で適当に探す。
https://github.com/search/advanced

clone 系の repository とか結構な規模があって、実験にちょうどよさそう。
package.json など見て、そこそこ依存 package の多いものを探す。

TL;DR

https://github.com/arx-8/discord-clone-ts-migrate/tree/ts-migrate-backend

Procedure

Summary

実 Project でやるなら、以下の順番でやるといいと思う(今回は eslint, prettier は省いた)

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 のためにも一括変換しておく方がよさそう。
  • 型なしコードを滅ぼしていきましょう。

参考記事

脚注
  1. JS -> TS に一括変換してれるツール。airbnb 製。 ↩︎

  2. ref.rule ごとに高速に eslint --fix できるツールを作った - mizdra's blog ↩︎

  3. JS/TS を一括編集してれるツール。transform の内容は自分で実装 or OSS を利用する。Facebook 製。moment.js の置換などもできる。date-fns 派だけど、moment 互換がこんな形で活きてるとは。(ref. jscodeshift で Moment.js を Day.js に一括置換した話 - ミツモア Tech blog) ↩︎

  4. jscodeshift 用 transformer。主に commonjs require/exports -> ES6 import/export の変換ができる。 ↩︎

Discussion