
Hemant Bhatt
November 20, 2025
TypeScript Omit: The Art of Removal

Introduction
Here's something nobody tells you about programming: half the job is removing things, not adding them. TypeScript's Omit utility type understands this. It's a scalpel, not a hammer. You point at what you don't want, and it disappears.
What Is Omit?
Omit<Type, Keys> takes a type and removes specific properties from it. That's it.
1 type User = { 2 id: string; 3 name: string; 4 email: string; 5 password: string; 6 }; 7 8 type PublicUser = Omit<User, "password">; 9 // Result: { id: string; name: string; email: string; }
You had four fields. Now you have three. The password is gone.
Why does this exist? Because typing out almost-identical types is tedious. Omit lets you be productively lazy.
Omitting Multiple Properties
Want to remove more than one property? Use a union type.
1 type User = { 2 id: string; 3 name: string; 4 email: string; 5 password: string; 6 createdAt: Date; 7 updatedAt: Date; 8 }; 9 10 type UserInput = Omit<User, "id" | "createdAt" | "updatedAt">; 11 // Result: { name: string; email: string; password: string; }
The syntax is Omit<Type, "key1" | "key2" | "key3">. Straightforward.
Pro Tip:
If you're omitting more properties than you're keeping, stop. Just write a new type.
Exclude vs Omit
People confuse these. Don't be people.
Omit: For Objects
Removes properties from object types
1 type User = { id: string; name: string }; 2 type NoId = Omit<User, "id">; 3 // { name: string }
Exclude: For Unions
Removes values from union types
1 type Status = "pending" | "active" | "deleted"; 2 type Active = Exclude<Status, "deleted">; 3 // "pending" | "active"
Deep Omit
Omit only works at the top level. Don't rely on it if you have deep nested properties. It just won't work.
1 type User = { 2 id: string; 3 profile: { 4 socialLinks: { twitter: string; github: string }; 5 }; 6 }; 7 8 type NoTwitter = Omit<User, "profile.socialLinks.twitter">; // ❌ Doesn't work
Common Patterns
API Responses: Hide Sensitive Fields
1 type UserFromDB = { 2 id: string; 3 name: string; 4 passwordHash: string; 5 }; 6 7 type UserResponse = Omit<UserFromDB, "passwordHash">;
Form Inputs: Remove Auto-Generated Fields
1 type Post = { 2 id: string; 3 title: string; 4 createdAt: Date; 5 }; 6 7 type CreatePostInput = Omit<Post, "id" | "createdAt">;
Omit vs Pick
Pick keeps properties. Omit removes them. Use whichever is shorter to write. That's it.
Using Omit
1 type User = { 2 id: string; 3 name: string; 4 email: string; 5 password: string; 6 }; 7 8 // Removing 1 property 9 type Public = Omit<User, "password">;
Using Pick
1 type User = { 2 id: string; 3 name: string; 4 email: string; 5 password: string; 6 }; 7 8 // Keeping 3 properties 9 type Public = Pick<User, "id" | "name" | "email">;
Common Mistakes
Mistake #1: Using Omit on Unions
Use Exclude instead.
1 // ❌ Wrong 2 type Status = "pending" | "active" | "deleted"; 3 type Active = Omit<Status, "deleted">; // Doesn't work! 4 5 // ✅ Right 6 type Active = Exclude<Status, "deleted">; // "pending" | "active"
Mistake #2: Thinking Omit Makes Fields Optional
It doesn't. Use Partial for that.
1 // Omit removes fields, doesn't make them optional 2 type User = { id: string; name: string; email: string }; 3 type NoId = Omit<User, "id">; // { name: string; email: string } 4 5 // Partial makes fields optional 6 type OptionalUser = Partial<User>; // { id?: string; name?: string; email?: string }
Mistake #3: Chaining Omit Calls
Use a union: Omit<T, "a" | "b">
1 // ❌ Verbose 2 type Step1 = Omit<User, "password">; 3 type Step2 = Omit<Step1, "createdAt">; 4 type Step3 = Omit<Step2, "updatedAt">; 5 6 // ✅ Clean 7 type Clean = Omit<User, "password" | "createdAt" | "updatedAt">;
Combining Utilities
Make Remaining Fields Optional
1 type User = { 2 id: string; 3 name: string; 4 email: string; 5 password: string; 6 }; 7 8 type UpdateInput = Partial<Omit<User, "id">>; 9 // { name?: string; email?: string; password?: string }
Make Remaining Fields Required
1 type User = { 2 id?: string; 3 name?: string; 4 email?: string; 5 }; 6 7 type StrictUser = Required<Omit<User, "id">>; 8 // { name: string; email: string }
Remember:
Chaining more than two utilities? Write a new type.
Conclusion
Omitremoves object properties.Excluderemoves union values. Don't confuse them.- For multiple properties:
Omit<T, "a" | "b">. For nested properties: flatten your types. - If it's getting complex, you're doing it wrong. Write a new type.
Now go delete something.
Happy typing!