typescript / expert
Snippet
Zero-Cost Nominales Typ-Branding über Einzigartige Symbol-Kapselung
TypeScript verwendet ein strukturelles Typsystem, was bedeutet, dass identisch aufgebaute Typen austauschbar sind. Nominales Branding simuliert nominale Typen, indem eine versteckte Typ-Markierung an ein einzigartiges Symbol gebunden wird. Dies verhindert Domain-Fehler (wie die versehentliche Übergabe einer OrderId an eine UserId-Funktion) ohne jeglichen JavaScript-Laufzeit-Overhead.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
declare const brandSymbol: unique symbol;export type Brand<T, B extends string> = T & {readonly [brandSymbol]: B;};type UserId = Brand<string, "UserId">;type OrderId = Brand<string, "OrderId">;function createUserId(raw: string): UserId {if (!raw.startsWith("usr_")) throw new Error("Invalid User ID format");return raw as UserId;}function createOrderId(raw: string): OrderId {if (!raw.startsWith("ord_")) throw new Error("Invalid Order ID format");return raw as OrderId;}function fetchUserOrders(userId: UserId): void {console.log(`Fetching orders for user ${userId}`);}const validUser = createUserId("usr_9981");fetchUserOrders(validUser);
Erklärung
1
declare const brandSymbol: unique symbol;
Deklariert ein einzigartiges Symbol, das nur zur Kompilierzeit verfügbar ist, um das Phantomeigenschafts-Branding zu steuern.
2
export type Brand<T, B extends string> = T & { readonly [brandSymbol]: B; };
Kombiniert den Basistyp T mit einer nicht instanziierbaren Eigenschaft, um eine strikte Typidentität zu erzwingen.
3
function createUserId(raw: string): UserId
Dient als Konstruktor-Validierungsfunktion, die einen primitiven String in eine Marke vom Typ UserId umwandelt.
4
function fetchUserOrders(userId: UserId): void
Beschränkt Parameter-Eingaben exklusiv auf gültige UserId-Brands und weist einfache Strings oder OrderIds zurück.