【にゅーたいぷぱたーん】

Newtypeパターン とは?

公開:
💡 同じ「数字」でも「ユーザーID」と「金額」を別物として扱う型の仕切り役
📌 このページのポイント
Newtypeパターン:型で意味を区別する int(整数型) 42, 1001, 9999 ... ⚠ 混同の危険 userId = orderId ? コンパイルが通ってしまう ↓ Newtypeパターンを適用 UserId wrap(int) ユーザーID専用の型 OrderId wrap(int) 注文ID専用の型 型が違うのでコンパイルエラー ランタイムでは同じint — パフォーマンスコストはゼロ コンパイル時のみ型として区別される
Newtypeパターン:同じ型でも意味ごとに別の型として区別する
ひよこ ひよこ
ペンギン先生、Newtypeパターンって普通の型と何が違うの?
ペンギン先生 ペンギン先生
例えば「ユーザーID」と「注文ID」がどちらも数値でも、Newtypeパターンを使うと型システム上は別物として扱えるんだよ。
ひよこ ひよこ
別物にしておくと、何かいいことがあるの?
ペンギン先生 ペンギン先生
うっかりユーザーIDを注文IDの引数に渡してしまうミスをコンパイル時に検出できるんだ。実行前にバグを発見できるよ。
ひよこ ひよこ
でも中身は同じ数値なんだよね?ランタイムのコストはかかるの?
ペンギン先生 ペンギン先生
それがNewtypeパターンの優れた点で、多くの言語では実行時にはただの数値として扱われてコストはゼロなんだよ。
ひよこ ひよこ
TypeScriptだとどうやって書くの?
ペンギン先生 ペンギン先生
TypeScriptでは `type UserId = string & { _brand: 'UserId' }` のようなBranded Typesという手法で似たことを実現するんだよ。
ひよこ ひよこ
なるほど!型に名前を付けるだけでバグを防げるなんて面白いんだね!
ペンギン先生 ペンギン先生
そうだよ。ドメイン駆動設計でも値オブジェクトの概念と親和性が高くて、設計の意図をコードで明示できる素敵なパターンだよ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「Newtypeパターン」って出てきたら「同じ型でも別物として扱うラッパー」と思えればだいたいOK!
📖 おまけ:英語の意味
「Newtype Pattern」 = 新しい型パターン
💬 Haskellの `newtype` キーワードに由来するパターンで、既存の型に新たな型名を付与しランタイムコストなしに型安全性を高める仕組みだよ
← 用語集にもどる