typescript / expert
Snippet
Branded-Email-Typen mittels Smart Constructors
TypeScripts strukturelles Typsystem behandelt jeden `string` als austauschbar — validierte Werte mischen sich unbemerkt mit Rohdaten. Ein Branded Type markiert ein Primitiv mit einer Phantom-Eigenschaft aus `unique symbol` und macht es so nominal unterscheidbar, ohne Runtime-Kosten. Ein `Email`-Wert kann nur über `parseEmail` entstehen, den Smart Constructor, der die Invariante erzwingt. Folgefunktionen vertrauen dem Brand und sparen sich defensive Nachvalidierung.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
declare const __brand: unique symbol;type Brand<T, B extends string> = T & { readonly [__brand]: B };type Email = Brand<string, "Email">;function parseEmail(raw: string): Email | null {return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(raw) ? (raw as Email) : null;}function sendMail(to: Email): void {console.log(`mailing ${to}`);}if (candidate) sendMail(candidate);
Erklärung
1
declare const __brand: unique symbol;
Eindeutiger Symbol-Schlüssel — garantiert kollisionsfrei zu Property-Namen.
2
type Brand<T, B extends string> = T & { readonly [__brand]: B };
Schneidet T mit einer Phantom-Property, die den Brand-String trägt.
3
return /.../.test(raw) ? (raw as Email) : null;
Smart Constructor: Die Assertion ist der einzige vertrauenswürdige Eintrittspunkt.
4
if (candidate) sendMail(candidate);
Aufrufer muss vorher narrowen — Rohstrings werden zum Typfehler.