単位の取り違えを防ぐブランド型・opaque型
基本型にphantom brandプロパティを交差させて単位やタグの取り違えを防ぎ、ファクトリ関数だけで値を生成します
「単位の取り違えを防ぐブランド型・opaque型」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全3レッスンが含まれています。
概要
目標: 型レベルで見た目が同じ値を区別します。通常の number だけではメートルと秒を区別できませんが、ブランドマーカーを使えば区別できます。
- 実行時のオーバーヘッドがゼロ
- より安全な API とリファクタリング
- ファクトリ経由でのみ作成する
プリミティブな単位にブランドを付ける
Brand マーカーによって、コンパイル時に単位を分離できます。引数の順序を間違えると型チェックに失敗します。
type Meter = number & { readonly __brand: "meter" }
type Second = number & { readonly __brand: "second" }
function meter(n: number): Meter { return n as Meter }
function second(n: number): Second { return n as Second }
const d = meter(100)
const t = second(9)
function speed(dist: Meter, time: Second) { return (dist as number) / (time as number) }
// speed(t, d) // compile error: brands do not match汎用的な Brand ヘルパー
ドメインをまたいで汎用的な Brand ヘルパーを使用します。型付き ID、トークン、カーソルなどに利用できます。
type Brand<Tag extends string, T> = T & { readonly __brand: Tag }
type UserId = Brand<"UserId", string>
type OrderId = Brand<"OrderId", string>
function userId(x: string): UserId { return x as UserId }
function orderId(x: string): OrderId { return x as OrderId }
function findUser(id: UserId) { /* ... */ }
const u = userId("u_123")
const o = orderId("o_456")
// findUser(o) // error: OrderId not assignable to UserIdunique symbol によるブランド付け
unique symbol によるブランド付けにより、名前の衝突やグローバル名前空間への漏れを防げます。
declare const MeterSym: unique symbol
type Meter2 = number & { readonly [MeterSym]: "meter" }
function asMeter2(n: number): Meter2 { return n as Meter2 }
const m2 = asMeter2(5)
// const wrong: Meter2 = 5 // discourage raw assignment; prefer factoriesファクトリとバリデーション
ファクトリの中でブランドを付与します。まず検証し、次にブランドを付け、その後で利用します。呼び出し側で場当たり的に as を使うのは避けてください。
type NonEmptyString = string & { readonly __brand: "NonEmpty" }
function nonEmpty(s: string): NonEmptyString | null {
return s.trim().length > 0 ? (s as NonEmptyString) : null
}
function makeSlug(s: NonEmptyString) {
return (s as string).toLowerCase().replace(/\s+/g, "-")
}
const ok = nonEmpty(" Hello ")
if (ok) { makeSlug(ok) } // safe: validated & branded firstヒントと注意点
ベストプラクティス:
- ブランド名は短く、意味が分かるものにしてください。
- ブランド付きの値を取得する方法は、ファクトリだけにしてください。
- 必要な場合を除き、公開 API の型にブランドを漏らさないでください。
- ブランドは型レベルだけのものであり、実行時のオーバーヘッドはありません。
ブランド付けの確認
クイックチェック: 単位やタグの取り違えを防ぐパターンはどれですか。
まとめ
まとめ: ブランド付き型や不透明型によって、見た目が似た値(メートルと秒、UserId と OrderId)を区別できます。ファクトリで生成し、API 全体で利用することで、誤った取り違えをなくせます。
AI チューターと学ぶ TypeScript — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 101
- レッスン
- 352
よくある質問
「単位の取り違えを防ぐブランド型・opaque型」レッスンは無料ですか?
はい。「単位の取り違えを防ぐブランド型・opaque型」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全3レッスンが含まれています。
「単位の取り違えを防ぐブランド型・opaque型」で何を学びますか?
基本型にphantom brandプロパティを交差させて単位やタグの取り違えを防ぎ、ファクトリ関数だけで値を生成します ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。
「単位の取り違えを防ぐブランド型・opaque型」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 単位の取り違えを防ぐブランド型・opaque型
- タグ付きIDとドメインモデリングのパターン
- ドメインモデリング — 集約、不変条件、サービス