TypeScript
JavaScriptに静的型付けを加えた言語。BenriWorksの全アプリと本サイトで使っています。数か月ぶりに戻るコードの仕様書として型を書き、frontmatterなどデータの境界はzodで実行時に検証しています。
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 のように単位を変数名へ埋め込む規約と、境界での変換関数の集約によって、単位の取り違えをコードレビューで見つけられる形にしています。
個人開発を低保守で継続するうえで、型による早期のエラー検出を重視しています。実装のなかで得た知見は開発記事として発信していきます。
この技術を使うアプリ

公開中
複線図道場
第二種電気工事士の技能試験に向けて、単線図から複線図を組み立てる練習と意味的な採点・診断を提供する学習アプリ
資格対策

プロトタイプ
LiveBrief
対面の商談やヒアリング中の音声をリアルタイムに文字起こしし、会話中の判断を支えるカードを提示する個人向け対話支援アプリ
業務効率化

ベータ版
構造化スタジオ
見積書などの紙の業務文書をLLMで構造化し、算術検算を通過したデータだけを蓄積するWindowsデスクトップツール
業務効率化

公開中
wavelane
陸上無線技術士の学習に向けて、電波伝搬をスライダー操作と3D断面図で体験しながら計算練習できる学習ツール
資格対策

公開中
地デジエリアマップ
現在地から地デジ中継局への方位・距離・受信の目安と放送区域を地図で確認できる、アンテナ方向合わせ支援アプリ
生活ツール

ベータ版
地球地下シミュレータ
地震波の伝わり方という観測データから地球の内部構造を推論する過程を、ブラウザで体験できる教育用3Dシミュレータ。PREM近似の層構造表示、P波・S波の波線追跡とシャドウゾーン、マントル対流の計算を備えます
科学・教育3Dシミュレーション

公開中
移動式クレーン安全シミュレーター
小型移動式クレーンの操作と危険を物理演算で再現し、転倒や荷振れを安全に体感できる教育用3Dシミュレーター
建設DX3Dシミュレーション
関連記事

ガイド公開
移動式クレーンの定格荷重とは — 作業半径との関係をわかりやすく
移動式クレーンの定格荷重・定格総荷重・つり上げ荷重の違いと、作業半径が大きくなるほど吊れる重さが減る理由を解説します。転倒災害の典型パターンと必要資格の区分もまとめます

ガイド公開
自由空間伝搬損失の計算 — 32.45の式の意味と覚え方
無線工学の頻出計算「自由空間伝搬損失」を、公式の意味から解説します。32.45+20log f+20log d の由来、距離2倍で6dB増える理由、試験での計算のコツをまとめます

ガイド公開
複線図の書き方 — 単線図から起こす手順を4ステップで解説
第二種電気工事士 技能試験の最初の壁である複線図を、単線図から起こす手順として解説します。書く順番の原則、電線の色の決まり、練習のコツをまとめます

ガイド公開
地デジが映らないときの切り分け手順 — 原因を順番に絞り込む
テレビが映らない・特定チャンネルだけ乱れるときに、症状から原因を絞り込む手順を解説します。E202などのエラー表示の見方、確認する順番、業者に頼む前にできることをまとめます

開発記事公開
教科書の式の不連続を、直さずにテストで固定する
学習ツールwavelaneで、ナイフエッジ回折の近似式に残る区分境界の不連続を、式を歪めずに既知の性質としてテストで文書化した判断を紹介します

開発記事公開
支持多角形でクレーンの転倒を判定する
クレーン安全シミュレーターで、支持多角形と安定余裕から転倒の危険を判定し、アウトリガーの張出しが効く理由を体感できるようにした実装を紹介します

開発記事公開
標高タイルで電波の見通しを判定する
地デジエリアマップで、国土地理院の標高タイルから地形断面を作り、中継局への見通し(山かげ)を判定した実装を紹介します

開発記事公開
LLMの読み取り結果を、検算を通ったときだけ信じる
構造化スタジオで、見積書の算術的な冗長性を利用し、決定論の検算を通過したデータだけを蓄積する設計を紹介します

開発記事公開
物理エンジンでクレーンの荷振れとワイヤー破断を表現する
クレーン安全シミュレーターで、振り子近似からRapier3Dの剛体とバネダンパーケーブルへ移行し、荷振れと破断を創発させた実装を紹介します

開発記事公開
音声認識ストリームの時間制限を、利用者に見せずに乗り越える
対話支援アプリLiveBriefで、クラウド音声認識のストリーム上限や無音切断を透過的なローテーションで吸収した実装を紹介します

開発記事公開
買い切りアプリのライセンスをオフラインで検証する
学習ツールwavelaneで、Ed25519署名トークンによりサーバー通信なしでライセンスを検証し、個人情報も持たない設計にした実装を紹介します

開発記事公開
マントル対流をWeb Workerでリアルタイムに計算する
教育用3D地球シミュレータで、渦度と流れ関数による対流計算をWeb Workerで安定して動かし続けた実装を紹介します

開発記事公開
地震波の波線追跡でシャドウゾーンを再現する
教育用3D地球シミュレータで、スネルの法則による波線追跡からS波シャドウゾーンを再現した実装を紹介します

開発記事公開
スマホのコンパス方位をWebで取得する
地デジエリアマップ(旧ARコンパス)の開発で、iOSとAndroidの方位センサーの違いを吸収し、安定した方位表示を実現した実装を紹介します

ガイド公開
テレビアンテナの向きを方位で合わせる方法
地デジアンテナを中継局に向けるための手順を、中継局の調べ方から方位合わせ、受信確認まで順に解説します

開発記事公開
Three.jsで移動式クレーンの荷振れを表現する方法
振り子運動と減衰を使った荷振れ表現の設計方針を、運動モデルとフレーム更新の観点から解説します

ガイド公開
クレーン安全教育に3Dシミュレーターを使う利点と限界
3Dシミュレーターをクレーンの安全教育に取り入れる場合の一般的な利点と、実機訓練や法令上の教育を代替できない限界を整理します