Branded Types: Safer ID Handling in React Native with TypeScript
Learn how to use TypeScript's branded types to prevent accidental mixing of different ID strings, reducing runtime bugs in React Native apps.
Insight
When your app talks to multiple back‑ends, you often end up with several ID shapes—userId, orderId, productId—all represented as plain strings. TypeScript treats them as interchangeable, so a typo can silently pass compile‑time checks and explode at runtime. Branded types give each ID a unique phantom property, letting the compiler enforce correct usage without adding runtime overhead.
Example
// Define a brand helper
type Brand<K, T> = K & { __brand: T };
// Create distinct ID types
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
// Helper to cast raw strings safely
const toUserId = (id: string): UserId => id as UserId;
const toOrderId = (id: string): OrderId => id as OrderId;
// Usage – compiler will reject mismatched IDs
function fetchUserOrders(userId: UserId) {
// fetch logic …
}
const uid = toUserId("u123");
const oid = toOrderId("o456");
fetchUserOrders(uid); // ✅ OK
// fetchUserOrders(oid); // ❌ Type error
Takeaway
Introduce branded types for any identifier that crosses module boundaries. The extra type safety catches mix‑ups at compile time while keeping the runtime footprint zero, leading to more robust React Native codebases.