Question

How to Exclude a Property from a Type in TypeScript

Question

I want to remove a single property from a TypeScript type. How can I do that?

For example, I have:

interface XYZ {
  x: number;
  y: number;
  z: number;
}

And I want to exclude the z property so the resulting type becomes:

type XY = {
  x: number;
  y: number;
};

Short Answer

By the end of this page, you will understand how to remove properties from existing types in TypeScript, especially with Omit. You will also see related alternatives like Pick, learn when each is useful, and understand how this pattern is used in real codebases to shape safer object types.

Concept

In TypeScript, you often start with a type that describes a full object, then need a smaller version of it.

A common example is when one property should not be included in a new type:

  • removing an id before creating a new record
  • removing a password before returning a user object
  • removing internal metadata from API output

Instead of rewriting the whole type manually, TypeScript lets you derive a new type from an existing one.

The standard utility type for this is Omit.

type XY = Omit<XYZ, "z">;

This means:

  • start with XYZ
  • omit the property named "z"
  • produce a new type containing the remaining properties

This matters because derived types are:

  • safer: fewer chances of inconsistencies
  • easier to maintain: update the original type once
  • clearer: they express intent directly

If XYZ changes later, your derived type updates automatically, except for the omitted keys.

Mental Model

Think of a TypeScript type like a checklist of fields on a form.

If the original form has:

  • x
  • y
  • z

Using Omit<XYZ, "z"> is like photocopying the form and covering up the z field with tape before printing. The new form still has everything else, but z is gone.

So:

  • Pick means keep only these fields
  • Omit means remove these fields

Both create a new type from an old one without rewriting everything by hand.

Take Quiz

Syntax and Examples

Core syntax

type NewType = Omit<OriginalType, "propertyToRemove">;

To remove multiple properties:

type NewType = Omit<OriginalType, "a" | "b">;

Your example

interface XYZ {
  x: number;
  y: number;
  z: number;
}

type XY = Omit<XYZ, "z">;

XY becomes equivalent to:

type XY = {
  x: number;
  y: number;
};

Using the new type

const point: XY = {
  x: 10,
  y: 20,
};

This is valid because point has only the required remaining properties.

Removing multiple properties

interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

type PublicUser = Omit<User, "password" | "email">;

PublicUser contains:

  • id
  • name

Older pattern using Pick and Exclude

Before Omit became the obvious choice, developers often wrote:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>;

This works too, but Omit<XYZ, "z"> is easier to read.

Step by Step Execution

Consider this example:

interface XYZ {
  x: number;
  y: number;
  z: number;
}

type XY = Omit<XYZ, "z">;

const value: XY = {
  x: 1,
  y: 2,
};

Here is what happens step by step:

  1. XYZ defines an object type with three properties: x, y, and z.
  2. Omit<XYZ, "z"> tells TypeScript to create a new type from XYZ without z.
  3. The resulting type XY has only:
    • x: number
    • y: number
  4. When value is declared as XY, TypeScript checks that:
    • x exists and is a number
    • y exists and is a number
    • no required property is missing
  5. z is not required, because it was omitted.

If you try this:

const badValue: XY = {
  x: 1,
};

TypeScript reports an error because y is still required.

If you use:

const anotherValue: XY = {
  x: 1,
  y: 2,
  z: 3,
};

TypeScript may reject it as an excess property in a direct object literal, because z is not part of XY.

Real World Use Cases

API responses

You may have a full database model but want to hide sensitive fields before returning data.

interface User {
  id: number;
  username: string;
  passwordHash: string;
}

type SafeUser = Omit<User, "passwordHash">;

Create requests

A record in the database may have an auto-generated id, but clients should not send it when creating a new item.

interface Product {
  id: string;
  name: string;
  price: number;
}

type NewProduct = Omit<Product, "id">;

UI view models

A frontend component may not need every backend field.

interface Article {
  id: number;
  title: string;
  body: string;
  internalNotes: string;
}

type ArticleCard = Omit<Article, "body" | "internalNotes">;

Form data

A form may collect only editable fields, not computed ones.

interface Profile {
  firstName: string;
  lastName: string;
  fullName: string;
}

type EditableProfile = Omit<Profile, "fullName">;
Take Quiz

Real Codebase Usage

In real projects, developers frequently derive types instead of rewriting them.

Common patterns

Hiding sensitive data

type PublicUser = Omit<User, "password" | "token">;

This is common in service layers and API handlers.

Request vs stored model

interface Order {
  id: string;
  total: number;
  createdAt: Date;
}

type CreateOrderInput = Omit<Order, "id" | "createdAt">;

The stored model has more fields than the input model.

Guarding function inputs

function createUser(input: Omit<User, "id">) {
  // create and assign id internally
}

This prevents callers from passing fields they should not control.

Combining with other utility types

type PartialUpdateUser = Partial<Omit<User, "id">>;

This means:

  • remove id
  • make the remaining fields optional

Useful for patch/update APIs.

Shared base type with specialized variants

interface Config {
  host: string;
  port: number;
  secretKey: string;
}

type PublicConfig = Omit<Config, "secretKey">;

This keeps one source of truth while allowing safer variants.

Common Mistakes

1. Rewriting the type manually

Beginners often do this:

interface XYZ {
  x: number;
  y: number;
  z: number;
}

type XY = {
  x: number;
  y: number;
};

This works, but it duplicates information. If x or y changes in XYZ, you must remember to update XY too.

Prefer:

type XY = Omit<XYZ, "z">;

2. Confusing Omit with Exclude

Broken example:

type XY = Exclude<XYZ, "z">;

Exclude works on union types, not object properties in this way.

Use:

type XY = Omit<XYZ, "z">;

3. Using a key that does not exist

type Bad = Omit<XYZ, "missing">;

Depending on context, this may not help you and may reflect a typo in your code design. Make sure the property name is correct.

4. Expecting runtime object removal

Omit only changes the type, not the actual JavaScript object at runtime.

interface XYZ {
  x: number;
  y: number;
  z: number;
}

type XY = Omit<XYZ, "z">;

const original = { x: 1, y: 2, z: 3 };
const typed: XY = original;

The runtime object still has z; only the type view has changed.

If you need to actually remove a property at runtime, use object destructuring:

const { z, ...withoutZ } = original;

5. Forgetting that omitted properties are gone from type checking

function printXY(value: Omit<XYZ, "z">) {
  console.log(value.z);
}

This is invalid because z no longer exists on that type.

Comparisons

ConceptPurposeExampleBest when
Omit<T, K>Remove properties from a typeOmit<User, "password">You want most fields except a few
Pick<T, K>Keep only specific properties`Pick<User, "id""name">`
Exclude<T, U>Remove members from a union type`Exclude<"a""b", "b">`
Manual type definitionWrite a new type from scratchtype XY = { x: number; y: number }The type is truly independent

Omit vs Pick

type A = Omit<XYZ, "z">;
type B = Pick<XYZ, "x" | "y">;

These are equivalent for this example.

Choose:

  • Omit when you want to remove a small number of fields
  • Pick when you want to keep a small number of fields

Omit vs runtime destructuring

const { z, ...rest } = obj;
  • Omit is type-level
  • destructuring is runtime JavaScript behavior

Often, real code uses both together.

Take Quiz

Cheat Sheet

// Remove one property
type Result = Omit<TypeName, "property">;

// Remove multiple properties
type Result = Omit<TypeName, "a" | "b">;

// Example
interface XYZ {
  x: number;
  y: number;
  z: number;
}

type XY = Omit<XYZ, "z">;

Quick rules

  • Omit creates a new type from an existing type
  • It does not remove properties at runtime
  • The second argument is the property name or union of names to remove
  • Use string literal keys like "z"

Related utility patterns

// Keep only some properties
type Small = Pick<XYZ, "x" | "y">;

// Remove from a union
type Letters = Exclude<"a" | "b" | "c", "c">;

// Optional fields after omitting
type PartialXY = Partial<Omit<XYZ, "z">>;

Good default choice

  • Use Omit when you already have the full type and want to remove a few fields.

FAQ

How do I remove one property from a type in TypeScript?

Use Omit:

type XY = Omit<XYZ, "z">;

Is Omit better than writing a new type manually?

Usually, yes. It avoids duplication and stays in sync with the original type.

Can I omit multiple properties at once?

Yes.

type PublicUser = Omit<User, "password" | "token">;

Does Omit remove the property from the actual object?

No. It only changes the TypeScript type. Use destructuring if you need runtime removal.

What is the difference between Omit and Pick?

  • Omit removes named fields
  • Pick keeps named fields

Both create a new type from an existing one.

Can I use Omit with interfaces and type aliases?

Yes. Omit works with object types whether they come from an interface or a type alias.

What if I need this in older TypeScript patterns?

You can write:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>;

But Omit is cleaner and easier to read.

Take Quiz

Mini Project

Description

Build a small TypeScript model for a user system where the full user record contains sensitive and system-generated fields, but the app needs safer derived types for public output and user creation. This demonstrates how Omit helps you reuse one base type while creating practical variants.

Goal

Create derived types from a base User type by removing fields that should not be exposed or provided by callers.

Requirements

  • Define a base User interface with at least id, name, email, and passwordHash.
  • Create a PublicUser type that excludes passwordHash.
  • Create a CreateUserInput type that excludes id.
  • Write example variables or functions that use these derived types.
  • Show at least one valid example for each derived type.
Take Quiz

Keep learning

Related questions

View more