TSKaigi 2026
utgwkk.icon スポンサーブースを回っていたらオープニングが始まりつつあることに気づかなかったのでなんかお知らせしてほしい
day1 オープニング
世界一のTypeScriptカンファレンス
Octverse 2025の調査で世界一使われているプログラミング言語ということになった
進化の年
マッサージなに
HERP
そもそも関数型プログラミングとは?
不変性
いろいろな概念を内包している
沼
TypeScriptで真の関数型プログラミングはできないのか?
真とは
制約を設ける
同一性
ID
構造的比較
純粋関数
暗黙の入出力がない
うっかり複数回呼び出してもOK
依存関係が関数の引数・戻り値のみで表現されている
字面の純粋性と意味の純粋性
副作用を表す値
HaskellのIOモナドに近づいていく
継続
Promise
コールバックAPI
継続渡しスタイル
コールバック地獄
Option型
モナドとして一般化できる
手続き的に書けるような糖衣構文を導入
型に効果が見える
継続は力なり
AI時代
AIの型知識をチェックする
だいたい知っていそう
フェッチ禁止で新しめの型について答えてもらう
型と集合論の関係
AIの解釈
型エラーが出ていたら直そうとしてくれる
RORO
Receiver Object, Return Object
ブランド型で情報量を増やす
Compiler APIでAST解析
Svelte + Hono
権限制御
ポリシーステートメント
権限制御の一貫性を整理する
同じ判定が複数レイヤーに現れる
できればDBで担保したい
RLS + ltree
権限モデルをSSoTとして管理する
valibot
DBとの値集合のズレを型で検出する
vitestで型をテスト
ブランド型
as const satisfies
守る対象に合わせて型・lint・テストを使い分ける
PostgreSQL上でTypeScriptで書いた権限ロジックを動かす手法
classも構造的部分型
thisの移動
useDefineForClassFields の有無でsetterのあるクラスをextendしたときの挙動が変わる
TypeScriptがES2015よりも先にclassを実装
TypeScriptの実装が先行したことによるECMAScriptとの差異
構造が合っていても instanceof が通らない
thisが変わる
値だけで成り立つ
Custom Error
classを使うかどうかは多くの場合フレームワークが決める
typescript-goのgo.modにMackerelのライブラリが使われている
デコレータ
--experimentalDecorators
reflect-metadata
--emitDecoratorMetadata
使い道
ログ
DI
ORM
Observable
Stage 3 Decoratorsとは
おおむね --experimentalDecorators
reflect-metadata
classの形を変えられると最適化戦略に関わってくる
引数デコレータがサポートされていない
代替手段がある
--emitDecoratorMetadata に対応していない
ライブラリ・フレームワークのインタフェースが変わってしまう
巨大なモノリスRails
erb + BackBoneなど
OpenAPI Schemaを使っているがなかなか進まない
Ruby側はSorbetで型を管理している
バックエンドの変更が即座にフロントエンドに反映される状態を作る
無理に疎結合にするのではなく、良い密結合を達成する
Prism
WASMが提供されているのでNode.jsから使える
RubyのコードからASTを抽出
TypeScript Compiler APIでTSのASTを組み立ててコード生成
複雑な型の生成はいったんやらない
メンテ不能になるのを回避
とはいえ欲しくはある
Sorbetの型アノテーションを使ったコード生成をやっていきたい
「届く」のレイヤー
Text
DIagnostics
Semantics
shellとgrep中心だとSemanticsが届かない
Codex
経路があることと、モデルが使うことは別
grepよりLSPが効く場合もある
日時の変換
Zod v4 Codec
スキーマを双方向変換できる
preprocess transform だと入力→出力の変換しかできない
VoidZero
Type-Aware Lintingだと並列化しづらい
oxlint-tsgolint
tsgolint側にルールを足したらいけるのでは?→失敗
oxlint側にもTypeScriptのルール定義がある
パフォーマンス悪化
JavaScriptはコンパイラを書くためにデザインされていない
Electronだと4GB memory limitがある
マルチコアを活かせない
言語選定
portであってrewriteではない
なぜGoなのか
ts-to-go
Goがサポートしない構文の移植
スナップショットテストとして書く
fuzzing
TSKaigi 2025のキーノート向けの私信
テレメトリを収集
Copilotに再現させて直す
本当に速いのか?
爆速の声が続々
なぜこんなに速いのか?
Parse→Bind→Check→Emit
並列コンパイル
Check以外は並列にしやすい
どう並列にCheckするのか
分割統治っぽい図が出ていたが
爆速の様子
TypeScript 6
なぜno-default-libを削除するのか
TypeScriptはバンドラではない
target: ES5 の削除
型の内部的な順序づけ
idに依存しないソート
--stableTypeOrdering
TS5/6の機能をGoにポートしていく
PR単位でやる
展望
新しいAPI体系
sync/async両方
Goは後方互換に優れた言語である
day2 オープニング
昨年よりかなり規模が大きくなっている
循環参照
なぜこうなっているのか
時代背景
Ajax
V8
Chakra
当時のJSツーリングは貧弱
アプローチ
AltJS
Dart
JS自体を直す
🔜Strada
Strada
既存のJSに型を足す
ドッグフーディング
IDE独特の要件
木がimmutable
親アクセスとimmutableの両立
red green tree
採用しなかった
2010年のJS
ES5が出たばかり
let, constがない
メモリ使用の問題
JITが未熟だった?
どうするか
immutabilityは活かせないので捨てる
メモリの消費を犠牲にする
親ポインタ
インクリメンタルパースを粗い粒度でやる
JSの環境に最適化してきたが限界が来る
Go port
10倍
単一バイナリ
値型
Goはメモリレイアウトが言語仕様レベルで保証されている
共有メモリ・マルチスレッド
Node.jsの共有・並列処理のための仕組みがのちのち出てきたが
制限がきつい
VSCodeだけの機能ではない
tsserver
Programmatic API
JSONプロトコル
VimScriptでtsserverとおしゃべりする例
これからどうなるのか
tsserverはなくなる
LSP
何がどうなるのか
embedded language対応はもうちょっと先になりそう
.vue
.svelte
tsserver <-> LSPの互換レイヤが不要になる
独自拡張を使っている場合はその限りでない
Programmatic APIへの影響
7.1以降になりそう
transform/emit周りをカスタムする口がなくなっているので厳しそう
Volar
ガードレールとしての型・テスト
ガードレールのない開発はいつか保守性が頭打ちになる
保守性とは変更容易性
ソフトウェアの「ソフト」とは変更しやすいということ
変更できないプログラムは死んでいる
人間とソフトウェアの関係
断絶=死
予期的変更容易性
恐怖
開放閉鎖原則
ソフトウェアアーキテクチャとは開放閉鎖原則を目指すものである
テスト駆動開発
経験的変更容易性
テストは開発者に構造上の問題を教える
テストを簡単に追加できるのがよい
テストはカナリアである
テスト駆動開発は開放閉鎖原則を徐々に満たすワークフロー
テスト駆動開発は先にテストを書きはじめることではない
変更しやすさは変更してみないとわからない
いつテストを書くか
予期的変更容易性の観点から考える
変更するのが怖いなら書く
不安がないなら書かなくていい
経験的変更容易性の観点から考える
構造上の問題を学習するために書く
もう変更しないなら書かなくてよいとも言える
テストピラミッド
リファクタリングで多くのテストが壊れることが構造上の問題のフィードバック
不安の解消→構造フィードバック
emitterで古いコードのトランスパイルをやらないようにする
Context-Sensitive Function
暗黙のthisによってcontext-sensitiveになる