本文へ移動
BenriWorks Lab

TypeScript

JavaScriptに静的型付けを加えた言語。BenriWorksの全アプリと本サイトで使っています。数か月ぶりに戻るコードの仕様書として型を書き、frontmatterなどデータの境界はzodで実行時に検証しています。

TypeScript公式サイト(外部サイト)

TypeScriptは、JavaScriptに静的型付けを加えたプログラミング言語です。BenriWorksでは、「移動式クレーン安全シミュレーター」「地球地下シミュレータ」を含む全アプリと、本サイトBenriWorks Labの開発に使用しています。

個人開発でこそ型が効く

型システムはチーム開発のためのものと語られがちですが、実感としては個人開発でこそ効きます。10を超えるアプリを一人で並行運用していると、数か月触っていないコードに戻ることが日常になります。そのとき「この関数は何を受け取り、何を返すのか」をコードそのものが説明してくれるかどうかが、再開の速度を決めます。型は未来の自分に宛てた仕様書として書いています。

もうひとつの実利は、リファクタリングの安全性です。たとえば本サイトのURL規約を末尾スラッシュ付きへ変更したとき、パス生成を単一のヘルパーに集約してあったため、変更点はほぼ1ファイルで済み、影響箇所はコンパイラが列挙してくれました。個人開発には他人のレビューがないぶん、コンパイラを最初のレビュアーとして扱う設計にしています。

データの境界はzodで検証する

型注釈はコンパイル時の約束にすぎず、外から入ってくるデータには効きません。BenriWorksでは、データがシステムに入る境界にzodによる実行時検証を置いています。

本サイトでは、記事やアプリ情報のfrontmatter(タイトル、公開日、下書きフラグなど)をビルド時にzodスキーマで検証し、不正なデータをビルド失敗として公開前に検出します。CMSを持たずMarkdownファイルを直接管理する構成では、この検証がCMSの入力バリデーションの代わりです。学習アプリの演習データや、シミュレーターのシナリオ定義といった構造化データも同じ方針で扱っています。スキーマから型を導出する(z.infer)ことで、検証ルールと型定義が食い違わないようにしています。

計算の単位をコードで区別する

シミュレーション系のアプリでは、数値の単位間違いが最も発見しにくいバグになります。電波伝搬の計算ならMHzとGHz、kmとm、dBと真数。荷振れの計算なら角度とラジアン。TypeScriptの型だけで単位を完全に守ることはできませんが、fMHz dKm のように単位を変数名へ埋め込む規約と、境界での変換関数の集約によって、単位の取り違えをコードレビューで見つけられる形にしています。

個人開発を低保守で継続するうえで、型による早期のエラー検出を重視しています。実装のなかで得た知見は開発記事として発信していきます。

この技術を使うアプリ

関連記事