Branded Types: Safer IDs in React Native with TypeScript
Use TypeScript's branded types to avoid mixing up identifiers (e.g., userId vs. postId) at compile time, reducing runtime bugs in mobile apps.
Insight
In many React Native projects, IDs are just string or number values. When you pass a userId where a postId is expected, TypeScript can't help, leading to subtle bugs. Branded (or nominal) types let you create distinct compile‑time types without runtime overhead, turning plain primitives into purpose‑specific identifiers.
Example
// Define a generic brand helper
type Brand<K, T> = K & { __brand: T };
// Create distinct ID types
type UserId = Brand<string, "UserId">;
type PostId = Brand<string, "PostId">;
// Helper to cast safely
const asUserId = (id: string): UserId => id as UserId;
const asPostId = (id: string): PostId => id as PostId;
// Usage in a component
function fetchUserPosts(userId: UserId) {
// fetch logic …
}
// compile‑time safety
fetchUserPosts(asUserId("u123")); // ✅
// fetchUserPosts(asPostId("p456")); // ❌ TypeScript error
Takeaway
Introduce branded types for any identifier that crosses component boundaries. They add zero runtime cost but catch mismatched IDs during development, making your React Native codebase more robust.