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
idbefore creating a new record - removing a
passwordbefore 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:
xyz
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:
Pickmeans keep only these fieldsOmitmeans remove these fields
Both create a new type from an old one without rewriting everything by hand.
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:
idname
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:
XYZdefines an object type with three properties:x,y, andz.Omit<XYZ, "z">tells TypeScript to create a new type fromXYZwithoutz.- The resulting type
XYhas only:x: numbery: number
- When
valueis declared asXY, TypeScript checks that:xexists and is a numberyexists and is a number- no required property is missing
zis 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">;
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
| Concept | Purpose | Example | Best when |
|---|---|---|---|
Omit<T, K> | Remove properties from a type | Omit<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 definition | Write a new type from scratch | type 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:
Omitwhen you want to remove a small number of fieldsPickwhen you want to keep a small number of fields
Omit vs runtime destructuring
const { z, ...rest } = obj;
Omitis type-level- destructuring is runtime JavaScript behavior
Often, real code uses both together.
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
Omitcreates 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
Omitwhen 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?
Omitremoves named fieldsPickkeeps 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.
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
Userinterface with at leastid,name,email, andpasswordHash. - Create a
PublicUsertype that excludespasswordHash. - Create a
CreateUserInputtype that excludesid. - Write example variables or functions that use these derived types.
- Show at least one valid example for each derived type.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Accessing Input Value from EventTarget in TypeScript
Learn why EventTarget has no value property in TypeScript and safely read values from HTML input events in Angular applications.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.