TSKaigi 2026に両日参加しました。聞いたトークのメモはCosenseにまとめてあります。
scrapbox.io
発表資料は TSKaigi 2026 発表資料まとめ にまとまっているので、こちらも見てみるとよいと思います。
話題
Branded Types
TypeScriptは構造的部分型を採用しており、型同士は名前ではなく構造によって区別されます*1。type UserId = string と type BlogId = string はどちらも同じ構造を持つため、UserId と BlogId は可換となります。
プリミティブ型に別名をつけて区別するためのテクニックとしてBranded Types (ブランド型) があります。典型的な実装としては以下のようになるでしょう。万が一 UserId と BlogId を取り違えても、型検査でエラーになるので実行前に気づくことができます。
declare const brand: unique symbol;
type Branded<T, Brand extends string> = T & {[brand]: Brand};
type UserId = Branded<string, 'UserId'>;
type BlogId = Branded<string, 'BlogId'>;
function getUser(id: UserId) {
}
getUser('blog' as BlogId);
今年のTSKaigiの発表を俯瞰してみると、Branded Typesをテーマとした発表が多かったような印象があります。個人的には、Branded Typesは知っているテクニックだったので新しさを見いだしづらいと思っていたけど、これは想定聴衆と自分がずれているということかもしれません。あとは「Branded Types + 活用事例」という構成だと、活用事例のほうだけ知りたいというのもあったかも。
クラス・デコレータ
クラスの継承を型注釈で表明する、みたいなことは誰か検討しなかったのかな? たぶん検討されているような気がする。
class Klass {}
function takeKlassInstance(x: instanceof Klass) {
}
function キーワードを使って関数を定義すると this が変わることについて、暗黙の第1引数が文脈に応じて渡されていると考えると急に腑に落ちました。とはいえ難しいのでできるだけ this に依存したコードを書くのを回避したいところでもありそう。
デコレータについて、使うと嬉しい場面があることは理解したけど、個人的にはだいたいなんでも関数で済ませるようになっているので、関数でよくない? と思っていました。後追いで標準化するにあたってエコシステムとのギャップが生じているのがむずかしそう。
いつテストを書くか
docs.google.com
lacolacoさんのトークが一番よかったというか、「TypeScriptに関連する発表」という型にとらわれず、考える切り口を示唆してくれるのがよかったと思います。これはTypeScriptにとどまらず「ソフトウェア」を書きたいなら一度発表資料を読んでみるべきです。
「TypeScriptコミュニティ」という括りについて思うこと
この件についてちょっと考えていたけど、TypeScriptを含めたJavaScript/Node.js/Webフロントエンド全般に関するコミュニティ*2が既に身近にあって、「TypeScriptコミュニティ」を分けて語るモチベーションに自分が共感できていないのだろう、と思うことにしました。すでにTypeScriptの言語機能や型の話がもう行われているし、コンパイラの内部実装や型の話を突き詰めることは誰も妨げないでしょう。TypeScriptに関する発見や困ったことがあれば近くの会でまとめて話したり、話を聞きに行ったりする、ぐらいでゆるくやっています。
話題をTypeScriptについて絞ることの作用というかトレードオフがたぶんあって、よりdeep diveした話題が増えるとか、似たようなテーマで切り口を工夫するみたいな感じになるのか、いろいろありそうな気はします。話題が広がりやすい形になっているといいな、と思います。
現状あんまりいい日本語が思いついていないので、気になる方は飲み会とかで自分を捕まえて聞き出してください。
プロポーザル
「フルスタックTypeScriptをチームとして開発できるようにやったこと」についてのプロポーザルを提出したのですが、落選しました。
運営の皆様、登壇者の皆様、今回のTSKaigiで話してくださった皆様ありがとうございました。
思い出したら追記します。