たゆたふ。

定まる所なく揺れ動き、いろいろやってみたメモ。など

GAS を Typescript でリファクタした

以前、GAS を Webpack と Babel でモダンに実装した話を書いた。

hero.hatenablog.jp

このエントリを要約すると次の通り。

  • Togglで記録した作業時間をRedmineの作業時間に登録する Google スプレドッドシートアドオンを作った。
  • google\/clasp を利用して、ローカルでコーディング、バージョン管理した。
  • ES6 で JS を書いて webpack + babel で GAS 用にビルドするようにした。

Claspが Typescriptをサポートした

まあまあモダンな JS で GAS を実装できる構成を確立したことで、今後はやりやすくなるぞと思ってから、半年ほど。

Clasp に驚くアップデートがあった。v1.5.0 で Typescript をサポートしたのだ。

qiita.com

clasp push コマンドを実行すると、JavaScript のコードを対応する GAS プロジェクトファイルにアップロードしてくれるのだが、Typescript のコードも自動的にコンパイルしてアップロードしてくれるようになったのだ。

もちろん、HTTP 通信には UrlFetchApp.fetch を使わないといけないとか GAS プラットフォームの制約はあるものの、コードのシンタックスは Typescript のものが使える。

つまり、次が使える。

型以外は webpack+babel の構成でも実現していたので、それほど目新しさはないが、webpack も babel も必要なく、これまで通りのコマンドを使うだけでトランスパイルしてアップロードしてくれる。

Toggl2rm を移行してみた

これは便利そうだということで、以前作ったToggl2rmを移行してみた。

移行前後のコードは次の通り。

依存モジュールが激減

移行前はこんな数のモジュールに依存していた。

  • @google/clasp
  • babel-core
  • babel-loader
  • babel-preset-env
  • babel-preset-gas
  • eslint
  • eslint-config-airbnb-base
  • eslint-plugin-googleappsscript
  • eslint-plugin-import
  • file-loader
  • gas-webpack-plugin
  • html-webpack-plugin
  • webpack

それが、移行後はたったの 3 つ。

トランスパイルに必要な一切を @google/clasp が担保してくれるので、 どんどんアップデートされる webpack や babel を追いかける必要もない。 その他必要なモジュールの組み合わせにも悩まされることもない。

@types/google-apps-script によって GAS 固有のクラス群にも型チェックできるようになるし、VSCode ならばコード補完が使えるのでドキュメントを確認する回数も減るだろう。

いいことしかない。

コードの書き換え

もともとのコードが ES6 だったこともありコードの書き換えも少なかった。

  • 拡張子を *.ts に変更する
  • 各関数の引数と戻り値に型アノテーションを追加
  • tslint のエラー箇所を修正
  • 変数 global を削除

ほぼこれだけで移行完了だった。

結構、関数コメントに引数や戻り値について書き込んでいたけれど、やはりコードで定義できるほうが確実だと思った。 そして、コード補完が感動的に便利。

いいことしかない。

まとめ

clasp で Typescript を使うのは簡単。

趣味レベルで使っている GAS のコードは作った後はそれほど頻繁にはいじらないと思う。そういうコードほど型アノテーションは恩恵があると思う。 また、ビルドの依存モジュールも少なくてコード以外のもののメンテナンスが最小化される。

GAS の実装で Typescript を使わない理由が見当たらない。