こんにちは。menu ユーザーフロントエンドチーム 松﨑です。
最近サーバーサイドチームでは PHP8移行 という大規模な移行作業が行われました。
言語のサポートバージョンが大きく変わると、既存のコードベース変更や動作確認は大変です。
そこでフロントエンド側として色々と思ったのが、今年3月に発表されたこの内容です。
発表されて「へえー Typescript 良くなるんや」と思いつつ、あまり深い部分まで理解できてなかったので掘り下げて調べてみることにしました。
これまでの道のり
Typescriptの歴史は Javascript の仕様を決める TC39 にも大きな影響をもたらしました。
今では当たり前のオプショナルチェーン(.?)やNull合体演算子(??)も、Typescriptで先に実装されていたものが普及した結果です。
生成AIフレンドリーな Typescript は、これからもフロント / サーバー問わず私たちが使うことになる多くの技術で採用されていくはずです。
もし開発ストーリー的なものに興味があれば、こちらのドキュメンタリーも視聴してみてください!Typescriptの生みの親であり移行プロジェクトをリードする Anders Hejlsberg 氏などのインタビューも聞けて面白いです。
Typescript7
Go移植の背景やそれによって何がもたらされるのかという部分を理解されたい方は こちらの記事 を一読することをおすすめします。
私の視点からも簡単に解説すると、
現在 Typescript チームでは コードネーム「Corsa」というプロジェクトが進行しています。typescript-goで公開されているGo移植プロジェクトです。
これにより Typescript7 からGoが移植されたコンパイラを使う未来が待ってます。今は tsgo としてOSSで実装されていますがゆくゆくは未来の tsc になります。
執筆時点でリリースされているTypescriptのバージョンは5.8.3ですが、この後メジャーバージョンが一つ上がってTypescript6 になります。このバージョンは Typescript7への移行期間でここで非推奨機能と互換性のない変更が入ります。
抑えておきたいのは、実装コードの実行速度が速くなるのではなく、コンパイル時間が今までより短縮されてTypescriptの開発体験が向上するだけであるということです。
基本的に、Typescriptコンパイラは
- 構文解析(Parsing)= tsファイルをASTへ
- 型チェック(Type Checking)= 型の整合性確認とエラー検知
- トランスパイル(Transpile)= tsファイルをjsファイルに変換
の順で動いて、私たちが最終的に実行している jsファイルやソースマップを吐き出します。
「Corsa」では、大きいプロジェクトだと時間がかかっていた型チェックの部分を改善するのが目標です。
余談ですが、
Corsa はイタリア語🇮🇹で「疾走」や「競争」を意味します。
ちなみに現在の Typescript5 や次回が最後になるであろう Typescript6 などJSベースのコードネームを「Strada」と呼んでいます。Stradaはイタリア語で「道」を表しています。「今までの道からよりスピードの出せる Typescript の世界になるぜ」という意味が込められているのかもしれません。
typescript-go はいまどんな感じ?
Typescript Native Preview 試してみた
さっそく公式のブログ記事にある通り、VSCodeに「TypeScript (Native Preview)」拡張機能をインストールしてコマンドパレットで有効化した後、
Next.jsのとあるプロジェクト(もちろんtscではエラーなし)を開いて tsgo を実行してみました。
npx tsgo --project tsconfig.json --strict
実行結果は、、、拍子抜けで普通にエラーもなくパスしました。
tsgoで検知できていないエラーがあるのかなと思い、いろいろ複雑な条件型などを使って型定義も試してみましたが、多くのコンパイルエラーはサポートされているように見受けられました
型チェックの機能は移植がかなり進んでいると言える気がします。
ちなみにパフォーマンスはソースコードの規模は32,059行に対して、
| コマンド | 実行時間(型チェック) |
|---|---|
tsc --project tsconfig.json --noEmit |
2.281s |
tsgo --project tsconfig.json --noEmit |
1.308s |
という計測結果でした。tsgoの方が少しだけ早くなってました。
コードベースが大きくなるとより効果を実感できるのかもしれません。
型チェックシステム
typescript-goではcheckerフォルダに型整合性をチェックするCheckerが存在します。
Checker は以下のような仕事をします。
- ASTから型情報を構築
- 型推論
- 型関係性チェック(ex: 変数代入できる?ある型と同一 or サブタイプか?など)
- 制御フローによる型の変化を追跡(ex: nullチェックの後の型絞り込み)
- 型エラーや警告の出力
型チェックのイメージを具体にすると、
1 . こんな単純なコードがあります。
let a: number = 1;
let b: string = a; // 型エラー
2 . コードはパースされると以下のようなASTになります(簡略化)
- VariableStatement (let a: number = 1;)
- name: "a"
- type: "number"
- initializer: NumericLiteral(1)
- VariableStatement (let b: string = a;)
- name: "b"
- type: "string"
- initializer: Identifier("a")
3 . ASTはGoで実装されたCheckerは checkTypeAssignableTo という関数を呼び出して、ASTから抽出した型情報を比較して a は b に代入できるかを比較します。
みたいな感じで整合性を確認します。(制御フローによる型はより複雑なので割愛)
ちなみにStrada(既存Typescript)の方は checker.ts にこのロジックが全て詰め込まれています。
LSP と Language Server
エディタ上で書くコードに対して、補完や型定義のクイック情報、定義移動などができるのは、LSP(Language Server Protocol) というプロトコルのもとで、エディタの背後にいる 言語サーバー(Language Server) が起動して通信しているからです。
LSPは、「Microsoftが標準化した言語ツールとコードエディタ間の通信プロトコル」です。
私たちがVSCodeにエクステンションをインストールして有効化すると、Language Serverが起動します。
https://code.visualstudio.com/api/language-extensions/language-server-extension-guide
一例ですが、VSCode上で以下のような操作をすると Language Serverへの通信してエディタ上に情報が表示されます。
| 構成要素 | 役割・機能 |
|---|---|
| completion | オートコンプリート候補の提供 |
| definition | 定義へのジャンプを可能にする |
| hover | カーソル上の情報表示 |
| diagnostics | エラー・警告などの表示 |
typescript-goでは lsフォルダ に言語サーバー(Language Service)の実装が定義されていてすべて go で書かれていることがわかります。
Language Service は 先ほど説明したCheckerと型情報についてやりとりします。
ちなみに言語サーバーと通信するクライアント(「TypeScript (Native Preview)」拡張機能)もtypescript-go内に _extensionフォルダ として既に実装されているのがわかります。
まとめ
現時点で、「Typescriptの表現のこの部分が変わるよ」などのアナウンスはないですが、Goで表現できないStrada(既存Typescript)の型表現などがあれば今後はTypescript6で段階的に廃止される可能性があります。
しかし、TypescriptとGoは同じ構造的型付け言語として相性がいいので選ばれたという技術選定の背景もあるので、廃止される型表現がそれほどは多くならないことを祈りたいです。
| 名前的型付け | 構造的型付け | |
|---|---|---|
| 型の区別基準 | 型の名前 | 型の構造 |
| 互換性の判断 | 名前が同じであれば互換性あり | 構造が同じであれば互換性あり |
| 主な採用言語 | Java, C#, Swift, PHPなど | TypeScript, Goなど |
typescript-goというプロジェクトを少しのぞていみて、改めて言語仕様を記述したプログラムは規模感に圧倒されますが、コンパイルの仕組みや言語サーバーのことを知ることでちょっと背伸びした気持ちになれました。
▼採用情報
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。
現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。
