How to Exclude Properties in TypeScript
Several techniques to create types without certain properties with examples
As a Typescript developer, I often need to work with types that have more information than I need. For example, I might have a type with many properties, let’s say 10, but I only need 5 of them.
Typescript Omit and Pick utility types
Omit
operator is a tool for creating new types from existing ones. Omit
creates new types by removing properties from existing types.
It’s great for creating variations of types. Think of it as a selective tool for your TypeScript types.
Here is the official documentation
1. Basic Example
Let’s say you have a type describing a car:
interface Car {
make: string;
model: string;
year: number;
color: string;
}
Now, you want a type just for basic car information, without the color. Here’s how Omit
helps:
type BasicCarInfo = Omit<Car, "color">;
let myCar: BasicCarInfo = {
make: "Honda",
model: "Civic",
year: 2022
// No color property here!
};
2. Omit to Exclude, Pick to Select
If you have a detailed User
type:
interface User {
userId: number;
name: string;
email: string;
isAdmin: boolean;
}
For displaying basic user information, you want to hide the userId
and isAdmin
fields:
type PublicUserInfo = Omit<User, "userId" | "isAdmin">;
Alternatively, you could build PublicUserInfo
by actively selecting desired properties:
type PublicUserInfo = Pick<User, "name" | "email">;
- Both
Pick
andOmit
create new types based on existing ones. Pick
is about taking what you explicitly want.Omit
is about removing what you don't want.
3. API Responses
You get a big chunk of data from an API with lots of fields. Here’s how Omit
to focus on essential parts:
interface APIProduct {
id: number;
name: string;
price: number;
// ... many more fields
}
type ProductSummary = Omit<APIProduct, "id" | /* other unnecessary fields */>;
4. Typescript Omit React props example
Let’s create a Simplified Button. Imagine you have a custom Button
component with several props:
import React from 'react';
interface ButtonProps {
onClick: () => void;
label: string;
size: "small" | "medium" | "large";
disabled: boolean;
type: "button" | "submit" | "reset";
}
const Button: React.FC<ButtonProps> = ({ onClick, label, size, disabled, type }) => {
// ...button rendering logic
};
Now, you want a new component, SimpleButton
, accepting only the essential button properties (like label
and onClick
).
Using Omit
with React Props
- Extract Props Type: Get the props type of your existing component.
type ButtonProps = React.ComponentProps<typeof Button>;
2. Omit Props: Use Omit
to exclude unneeded props.
type SimpleButtonProps = Omit<ButtonProps, "size" | "disabled" | "type">;
3. Create the Simplified Component:
const SimpleButton: React.FC<SimpleButtonProps> = ({ onClick, label }) => {
// ... button rendering with default size, not disabled, etc.
};
- Here we use
React.ComponentProps
to get the correct type for theButton
component's props. Omit
allows us to define new type for ourSimpleButton
based onButton
propsOmit
ensures type safety, preventing you from accidentally passing unused props to the simplified component.
Other ways to exclude properties from type
- Destructuring with Rest
Destructuring combined with rest patterns provides a way to extract specific properties while simultaneously omitting others. Here’s how it works:
interface Person {
name: string;
age: number;
city: string;
}
const person: Person = { name: "Alice", age: 30, city: "New York" };
const { name, ...rest } = person;
console.log(name); // Output: "Alice"
console.log(rest); // Output: { age: 30, city: "New York" }
In this example, we capture the name
property and gather the remaining properties into the rest
object. Effectively, rest
is like a type without the name
property.
2. Manually Creating New Types (simplest, but not recommended way)
You can simply define a new type and list the properties you want to include:
interface Book {
title: string;
author: string;
pageCount: number;
}
interface BookSummary {
title: string;
author: string;
}
Here, BookSummary
omits the pageCount
property by simply not including it in the definition.
3. Type Intersection with never
A slightly more advanced approach involves type intersections and the never
type:
interface Employee {
id: number;
name: string;
role: string;
}
type EmployeeWithoutRole = Employee & { role: never };
Here, we intersect Employee
with an object where role
is explicitly set to never
. Since a property cannot have never
, it's effectively removed in the resulting EmployeeWithoutRole
type.
Enjoyed the read? Hit 👏 like it’s a high-five — to motivate me to bring more stories!
I’m always looking to meet new people in tech. Feel free to connect with me on LinkedIn!