TSKaigi 2026 に初参加 – 型は開発者をハッピーにする

こんにちは。Legalscape SRE・カイゼンチームの橋本です。

2026年5月22日〜23日にベルサール羽田空港で開催されたTSKaigi 2026に参加してきました。 私は初参加でしたが、参加者数が多く、TypeScript(以下、TS)に関するアンケートボードへの書き込みも積極的に行われていて、活気あふれるカンファレンスでした。 またノベルティにあったTSKaigi 2026 PASSPORT (メモ帳) とペンに助けられました。(初日はスマホとPCのバッテリーが切れていた...)ありがとうございました。

今回はそんな活気あふれるカンファレンスで気になったセッションを紹介します。

1. 権限チェックの一貫性を型で守る TypeScript による多層防御

speakerdeck.com

権限制御は頭を抱えたくなる課題の一つだと思います。このセッションでは、守りの根幹をDBに置き、他のレイヤーはそれに合わせて展開するという手法を用いていました。また権限モデルをSSoTとして定義し、テストやBranded Types、satisfies、リンターなどを駆使することで一貫性を保っていました。

個人的には、PostgreSQLのplv8(V8ベースのJS 実行環境)を用いて、アプリ層のバリデーションとDBのCHECK制約を同一のスキーマ定義で制御するのは面白いアイデアだなと思いつつ、若干怖いなという所感も持ちました。保守運用面を考えると、ベンダーロックインや例外的な対応による複雑化や煩雑化を生みそうなためです。
実運用にはそうした懸念もあるものの、適材適所で型の実装方法やライブラリを選定すれば、安全性を高めることは可能です。DBでの実行環境までも選択肢に入るというTSのポテンシャルを知り、フルスタック開発においてより一層活用しやすく、良い言語だと改めて感じることができました。

開発について様々な視点で考えるきっかけとなり、また普段あまり触れていない知識や他社の経験を聞けて大変良い機会でした。

2. スプレッド構文によるブランド流出問題を乗り越えて、オブジェクト型に対する Branded Types を使い倒す

www.docswell.com

Branded Types自体は以前から使われていた手法ですが、TSKaigi 2026ではBranded Typesに関するセッションが比較的多く、知見が深まりました。

TSは構造的型付け(Structural Typing)を採用しているため、例えばUserIdCompanyIdという異なる意図を持つ型であっても、内部構造(どちらもただの文字列など)が同じであれば代入できてしまい、エラーになりません。それを回避するための手法としてBranded Typesがあり、具体的には、型定義に __brand(下記ではunique symbolをキーにしている)といった識別子となるプロパティを交ぜることで、型が判別可能になります。

brand.ts

export type Brand<T extends symbol> = { readonly [K in T]: unknown };

user.ts

import type { Brand } from "./brand";
declare const userIdSymbol: unique symbol;
export type UserId = string & Brand<typeof userIdSymbol>;
export type User = { readonly id: UserId; readonly name: string };
export const createUser = (name: string): User => ({ id: crypto.randomUUID() as UserId, name }) ;

main.ts

import { createUser, type User } from "./user";
const validUser: User = createUser("Alice");
const invalidUser: User = { id: "u_123", name: "Bob" }; // 型エラー: id が UserId ではない

引用元:スプレッド構文によるブランド流出問題を乗り越えて、オブジェクト型に対する Branded Types を使い倒す @TSKaigi 2026 | ドクセル

このセッションではもう一歩踏み込んでいて、スプレッド構文を用いたときのブランド流出を防ぐというものでした。

main.ts

/*
  確認: DateRange は以下のような構造をしている
  {
    readonly start: Date;
    readonly end: Date;
    readonly [dateRangeSymbol]: unknown;
  }
  ブランドは所詮ただのプロパティであることに注意
*/
const invalidDateRange: DateRange = {
  ...validDateRange,
  start: new Date("2026-05-23T17:10:00"),
  end: new Date("2026-05-23T16:40:00"),
}; // 型エラーにならない 😱

引用元:スプレッド構文によるブランド流出問題を乗り越えて、オブジェクト型に対する Branded Types を使い倒す @TSKaigi 2026 | ドクセル

これを厳格にするために、classprivateフィールドを使う手法が紹介されており、とても納得感がありました。このような手法を思いつくとワクワクしますし、実際にうまく行ったときは気持ち良いですよね。気になる方はぜひスライドを見てみてください。

このセッションで特に良かった点が、この手法を.d.ts経由で利用する際の注意点や、実運用での適用範囲、移行容易性も含めて説明されていたところです。ハックのような手法をチーム開発に採用するのは若干の怖さもありますが、こうした丁寧な説明があることで導入の心理的ハードルが下がり、実際の現場でも実践しやすいと感じました。

3. いつテストを書くか?―ソフトウェア開発における安心と不安について考える

参考:2026-05-23 いつテストを書くか? (TSKaigi 2026) - Google スライド

昨今のAI時代に関わらず、以前からテストは重要視されていますが、テストの保守運用が大変で後回しにしているケースもあると思います。

このセッションではコードの変更容易性を予期的変更容易性と経験的変更容易性に分けて説明されていて、興味深かったです。前者は変更への心理的なハードルが低いと良く、後者は実際の変更が容易だと良いとしていました。またテストを書くことで変更への心理的ハードルが低くなるだけでなく、変更を加えた際にテストが壊れる(影響を受ける)ことが、コードの構造的な問題に気づくきっかけになるのだと理解しました。

私は以前、パッケージのバージョンアップグレードを試した際にテストケースのない動作確認で見落としがあり、テストの重要性を痛感した記憶があったため、テストは変更の心理的ハードルを低くするという示唆に共感しました。

まとめとして、登壇者は「いつテストを書くか?」の問いに対して次のような視点で提案していました。

ソフトウェアの振る舞いが不安なときにテストを書く

引用元:2026-05-23 いつテストを書くか? (TSKaigi 2026) - Google スライド


ソフトウェアの構造を最適化したいときにテストを書く

引用元:2026-05-23 いつテストを書くか? (TSKaigi 2026) - Google スライド

私もこちらの視点は1つの解だと思いますし、このセッションと最近の経験を通して、テストはチームメンバーへの思いやりであり、将来の自分への投資だと考えるようになりました。

全体的な感想

TSKaigi 2026では、Branded TypesとSSoTに関するセッションが比較的多かった印象です。 セッションはLeveragesトラック・UPSIDERトラック・RightTouchトラックの3部屋で同時に進行されたため全ては見れませんでしたが、異なるコンテキストの課題に対してもBranded Typesが有効であることや、バックエンドやDBの実装をSSoTとした開発の知見が深まりました。 また本記事では触れませんでしたが、カスタムESLintを用いることで一貫性のあるコードを担保する手法も興味深く、学びのあるTSKaigi 2026でした。ありがとうございました。

最後に

AIのコード生成量が増えた昨今ではコードの一貫性と開発スピードを両立することがより難しく感じますが、弊社ではこのようなカンファレンスに参加するメンバーも多く、日々インプットして改善に努めています。一緒に開発できる仲間を探していますので、ご興味のある方はぜひお気軽にご連絡ください!