~/swaraj.dev
Back to all posts
May 18, 20262 min read

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.

typescriptreact-nativetype-safety

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.