CodexBloom - Programming Q&A Platform

TypeScript: How to type a function that conditionally modifies an object's properties based on a type guard?

πŸ‘€ Views: 15 πŸ’¬ Answers: 1 πŸ“… Created: 2025-06-09
typescript type-guards type-safety TypeScript

Hey everyone, I'm running into an issue that's driving me crazy. I'm trying to create a function in TypeScript that modifies an object's properties based on certain conditions. I want to ensure the function is type-safe, but I'm running into issues with properly inferring types when using type guards. Here’s a simplified version of what I have: ```typescript interface User { id: number; name: string; age?: number; } interface Admin extends User { role: 'admin'; } interface Guest extends User { role: 'guest'; } type UserRole = Admin | Guest; function updateUser(user: UserRole, updates: Partial<User>): UserRole { if (user.role === 'admin') { // If the user is an admin, we can safely add a property return { ...user, ...updates } as Admin; } // If the user is a guest, we'll modify differently return { ...user, ...updates } as Guest; } ``` The question arises when I try to use this function. For example, when I call `updateUser({ id: 1, name: 'Alice', role: 'admin' }, { age: 30 });`, TypeScript throws an behavior saying that `age` does not exist on type 'Admin'. This is because I defined `age` as an optional property on `User`, but `Admin` does not have `age` defined explicitly. I've tried using type assertions and narrowing down the types more explicitly, but I need to seem to get TypeScript to recognize that the `updates` can contain properties that are valid for both `Admin` and `Guest`. Is there a way to structure this function to avoid these type errors while keeping TypeScript's type safety intact? I'm using TypeScript version 4.3.5 and I'd really appreciate any insights or best practices here. What would be the recommended way to handle this?