Branded Types: Safer IDs in React Native with TypeScript
Use TypeScript branded types to prevent accidental ID mix‑ups across entities in your React Native codebase.
Insight
When a mobile app talks to several back‑ends, it's easy to accidentally pass a userId where a postId is expected—both are just strings at runtime. TypeScript's structural typing means the compiler can't catch this, leading to subtle bugs. Branded (or nominal) types give you a lightweight way to differentiate IDs at compile time without runtime overhead, keeping your codebase safe while staying ergonomic for React Native development.
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 factories (runtime‑free)
const userId = (id: string): UserId => id as UserId;
const postId = (id: string): PostId => id as PostId;
// Usage in a component
function fetchPost(user: UserId, post: PostId) {
// TypeScript will error if you swap the args
console.log(`User ${user} requests post ${post}`);
}
// Correct call
fetchPost(userId('u123'), postId('p456'));
// ❌ compile error: Argument of type 'PostId' is not assignable to parameter of type 'UserId'
Takeaway
Introduce branded ID types for every entity that uses a primitive identifier. The extra one‑line type definition prevents accidental cross‑entity ID usage, catches bugs at compile time, and adds zero runtime cost—making your React Native app both safer and cleaner.