【入門編】 Nominal Typingのシミュレーション – TypeScript実践ガイド

こんにちは!フロントエンドの現場で日々コードと格闘しているチーフアーキテクトです。

TypeScriptを触り始めると、必ず一度は「あれ、なんでこれで通っちゃうの?」という瞬間に遭遇しますよね。実はTypeScriptの優しさは、時に「お節介」にもなり得ます。

今日は、そんなTypeScriptの「構造的部分型」という少し変わった性格を、「ブランド(Brand)パターン」という必殺技でコントロールするお話をしましょう。初心者の方でもスッと腑に落ちるよう、身近な例えで解説していきますね。

—

1. なぜ「なんでもアリ」になってしまうのか?

TypeScriptは「中身が同じなら同じものとみなす」という性格をしています。これを「構造的部分型」と呼びます。

例えば、こんな状況を想像してください。

type UserId = string;
type ProductId = string;

const user: UserId = “user_01”;
const product: ProductId = “user_01”; // 本来は別のものなのに!

// 中身がどちらも文字列だから、TypeScriptは怒らない
const doSomething = (id: UserId) => { / … / };

doSomething(product); // !!エラーにならない!!

「商品ID」を渡すべきところに「ユーザーID」を渡してしまったら、バグの温床ですよね。でもTypeScriptは「どちらも文字列じゃん、OKOK!」とスルーしてしまいます。これが現場で意外と怖い「型は合っているのに中身が違う」という事故です。

—

2. そこで登場!「ブランド(Brand)パターン」

これを防ぐのが「Nominal Typing(名前による型判定)」のシミュレーションです。

イメージとしては、「中身はただの文字列だけど、わざわざ『これはユーザーIDというラベルがついた箱です』と刻印を押す」ような作業です。

刻印を押すコード

// インターフェースに「__brand」という架空の刻印を忍ばせます
type UserId = string & { readonly __brand: “UserId” };
type ProductId = string & { readonly __brand: “ProductId” };

// 刻印を押すための小さな関数(キャストを使います)
const toUserId = (id: string) => id as UserId;
const toProductId = (id: string) => id as ProductId;

const myUser = toUserId(“user_01”);
const myProduct = toProductId(“user_01”);

function deleteUser(id: UserId) {
console.log(“ユーザーを削除します”, id);
}

// 試してみよう!
deleteUser(myUser); // OK!
// deleteUser(myProduct); // !!ここでTypeScriptが激怒してくれる!!
// 「’__brand’ プロパティがないのでダメですよ!」と教えてくれます。

見てください!たったこれだけで、TypeScriptが「それはユーザーIDじゃないからダメ!」と止めてくれるようになります。

—

3. なぜこれが「現場の知恵」なのか?

「いちいち刻印を押すの、面倒じゃない?」と思うかもしれません。確かに、小さなプログラムなら不要です。

でも、数万行を超えるような大規模なWeb開発では、この「間違いを未然に防ぐコスト」が、後の「デバッグに費やす膨大な時間」を救ってくれるんです。

  • APIからのレスポンスを扱うとき:バックエンドから来たデータに、この刻印を押してからドメイン層に渡す。
  • 関数の引数ミスを防ぐ:IDの種類が複数ある複雑な画面で、型安全をガチガチに固める。

これは、現場のアーキテクトが「自分やチームメイトが将来ミスをしないための仕掛け」としてよく使う手法なんですよ。

—

4. 最後に:怖がらなくて大丈夫です

最初は「`& { readonly __brand: … }` って何?」と難しく感じるかもしれません。でも、大丈夫。これは「TypeScriptに、僕らの意図(これはユーザーIDなんだ!)を伝えるための魔法の呪文」だと思ってください。

まずは、自分のコードの中で「これとこれは混ざっちゃいけないな」と思うIDの型定義に、一つずつ刻印を押すところから始めてみてください。

最初は手探りでいいんです。その小さな積み重ねが、いつかあなたの書くコードを「世界で一番堅牢で美しいコード」へと進化させてくれますよ。

もし途中でつまずいたら、いつでもまたここへ戻ってきてくださいね。応援しています!

コメント

タイトルとURLをコピーしました