Omit Utility Type in TypeScript

Omit creates a new type by removing specific properties from an existing type. Use it when it is easier to say what to exclude than what to include.

6 min read

The TypeScript Omit utility type creates a new type by removing specific properties from an existing type. You pass it a type and a union of property names to exclude. The result is everything from the original type except the named fields.

Omit is the complement of Pick utility type in TypeScript. Pick includes only the properties you name, while Omit includes everything except the properties you name.

When you want most of a type's fields and only need to drop a few, Omit is the clearer choice.

typescripttypescript
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
  createdAt: Date;
}
 
type SafeUser = Omit<User, "password">;

SafeUser has every property from User except password. If you try to add password to a SafeUser object, the compiler rejects it. This pattern is common when sending user data to the client: you want all fields except the sensitive ones, and listing every safe field by hand would be easy to forget as the User interface grows.

How Omit works

Omit takes two type arguments. The first is the source object type. The second is a union of string literal types for the keys to remove:

typescripttypescript
interface Product {
  id: number;
  title: string;
  price: number;
  stock: number;
  internalCode: string;
}
 
type PublicProduct = Omit<Product, "internalCode" | "stock">;

Two properties are removed. The result has three fields: id, title, and price.

If Product gains a new property later, PublicProduct automatically includes it, unless you also add that new property to the Omit union. This makes Omit a good choice when your public type should stay close to the internal type, since you only maintain a short exclusion list instead of a long inclusion list.

Omit vs Pick: when to use which

Both Omit and Pick can produce the same type. The difference is in which one reads more naturally for your use case.

ScenarioUseWhy
Removing 1 or 2 sensitive fieldsOmitNaming what to remove is clearer
Selecting 2 or 3 display fieldsPickNaming what to keep is clearer
Type has many properties, want mostOmitAvoids listing 20 fields
Type has many properties, want fewPickAvoids listing 20 exclusions

The next example shows the same result expressed both ways on a larger interface, so you can compare how each reads. Start with a report type that has both internal and public fields:

typescripttypescript
interface FullReport {
  id: number;
  title: string;
  body: string;
  author: string;
  status: string;
  createdAt: Date;
  updatedAt: Date;
}

Omit removes the two internal fields and keeps everything else, while Pick would need to name all five public fields to reach the same result:

typescripttypescript
type PublicReport = Omit<FullReport, "status" | "updatedAt">;
type PublicReportPick = Pick<FullReport, "id" | "title" | "body" | "author" | "createdAt">;

Both lines produce the same type. The Omit version is easier to read and maintain because it says what to remove instead of listing everything to keep. If FullReport gains a new public field, the Omit version includes it automatically, but the Pick version needs to be updated by hand.

Omit for form data types

Forms often exclude server-managed fields, such as an id assigned by the database or timestamps set automatically when a record is created or updated. Omit makes it simple to describe exactly what a form should collect.

typescripttypescript
interface Task {
  id: number;
  title: string;
  description: string;
  dueDate: Date;
  completed: boolean;
  createdAt: Date;
  updatedAt: Date;
}

A create-task form should not ask the user for an id, a completion flag, or timestamps, since the server fills those in. Omit removes exactly those fields, and the resulting input type feeds into a function that builds the full Task:

typescripttypescript
type CreateTaskInput = Omit<Task, "id" | "createdAt" | "updatedAt" | "completed">;
 
function createTask(input: CreateTaskInput): Task {
  return {
    ...input,
    id: Math.random(),
    completed: false,
    createdAt: new Date(),
    updatedAt: new Date(),
  };
}

The function accepts the fields the user provides and fills in the server-managed fields itself. CreateTaskInput stays in sync with Task automatically. If you add a new field to Task that the user should provide, CreateTaskInput includes it by default, without you having to touch the form type at all.

Omit does not error on missing keys

Unlike Pick, Omit does not complain if you try to remove a key that does not exist on the source type. This is a small but important difference between the two utility types.

typescripttypescript
interface Widget {
  name: string;
  price: number;
}
 
type Result = Omit<Widget, "name" | "color">;

The compiler silently ignores "color" because it is not a key of Widget. This can hide typos. If you meant to write "price" but typed "prcie", Omit would ignore the typo and leave price in the type, which is easy to miss during a code review.

Constraining the second type argument to only valid keys catches this kind of mistake at compile time instead:

typescripttypescript
type StrictOmit<T, K extends keyof T> = Omit<T, K>;
 
type Safe = StrictOmit<Widget, "prcie">;
// Error: Type '"prcie"' does not satisfy the constraint 'keyof Widget'.

The constraint forces K to only be keys that actually exist on T. This is useful in library code or any place where you want stricter checks than the built-in Omit provides.

Combining Omit with other utility types

Omit composes well with other utility types. A common pattern is Omit plus Partial utility type in TypeScript for update payloads, where some fields should never change and the rest are optional:

typescripttypescript
interface Article {
  id: number;
  slug: string;
  title: string;
  body: string;
  publishedAt: Date;
}
 
type ArticleUpdate = Partial<Omit<Article, "id" | "slug">>;

First Omit removes id and slug entirely. Then Partial makes the remaining fields optional. The result is a type where title and body can be provided or omitted in an update, but id and slug can never be changed through this type.

Common mistakes

Using Omit when Pick would be clearer. If you are only keeping 2 out of 15 properties, use Pick to name the 2 you want directly. Naming a couple of fields to keep is more readable than a long Omit that lists 13 exclusions.

Relying on Omit to strip properties at runtime. Omit is compile-time only. If you send a full User object to a function typed as Omit&lt;User, "password"&gt;, the password is still there at runtime, because the type annotation only controls what the function body is allowed to read.

You still need to explicitly remove sensitive fields from the actual object before sending it to a client.

Forgetting that Omit only removes top-level properties. Like other utility types, Omit is not deep. Removing a nested field name directly does nothing, because that name is not a top-level key of the outer object. You would need to omit the whole nested object, or write a recursive type to reach inside it.

Rune AI

Rune AI

Key Insights

⚠ This article has a formatting issue and may not display correctly.

Our team has been notified. The content is shown as plain text below.

- Omit creates a type by removing the properties named in K from T. - Use Omit when you want most properties and only need to drop a few. - Use Pick when you only want a few properties and it is clearer to name them. - Omit does not error on keys that do not exist in the source type. - Like all utility types, Omit is compile-time only.
RunePowered by Rune AI

Frequently Asked Questions

Is Omit the same as Exclude?

No. Omit works on object types and removes keys. Exclude works on union types and removes members. `Omit<{a:1,b:2}, 'a'>` produces `{b:2}`. `Exclude<'a'|'b', 'a'>` produces `'b'`.

What happens if I Omit a property that does not exist?

The compiler does not complain. Omit removes the specified keys from the type's key set. If a key is not in the original set, removing it has no effect. This is different from Pick, which requires every key to exist.

Is Omit better than Pick?

Neither is better. Use Omit when you want most properties and only need to remove a few. Use Pick when you only want a few properties. Choose whichever makes the intent clearer.

Conclusion

Omit is Pick's complement. When you want most of a type's properties and only need to remove a few, Omit is clearer than listing every field you do want. Use it for DTOs that exclude sensitive fields, form types that exclude auto-generated fields, and any type that is one or two removals away from what you need.