Question
I have an array in TypeScript where each item contains a property that I use as a key. If I know that key, how can I remove the matching item from the array?
For example:
type User = {
id: number;
name: string;
};
const users: User[] = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
If I know the id, what is the correct way to remove the corresponding item from the array?
Short Answer
By the end of this page, you will understand how to remove objects from a TypeScript array when you know a key such as id. You will learn the difference between mutating and non-mutating approaches, when to use filter() or splice(), and how this is commonly handled in real codebases.
Concept
In TypeScript, arrays do not have a built-in removeByKey() method. To remove an item, you usually:
- find the item’s index and remove it with
splice(), or - create a new array without that item using
filter().
This matters because arrays are one of the most common data structures in applications. You often store lists of users, products, tasks, messages, or API results as arrays of objects. Removing an item by a key like id is a very common operation.
There are two important styles:
- Mutable removal: changes the original array
- Immutable removal: returns a new array and leaves the original unchanged
In TypeScript, both approaches are valid. The best choice depends on your situation:
- Use
splice()if you want to update the existing array in place. - Use
filter()if you want a cleaner, safer approach that returns a new array.
Because TypeScript adds type checking, it helps ensure that your array items and keys are used correctly. For example, if id is a number, TypeScript can catch mistakes where you compare it to a string.
Mental Model
Think of an array like a row of labeled boxes.
Each box contains an object, and each object has a label such as id.
If you want to remove one box:
- With
findIndex()+splice(), you first walk along the row, find the box number, then physically pull that box out. - With
filter(), you build a brand-new row containing only the boxes you want to keep.
So:
splice()= remove from the existing rowfilter()= create a new row without the unwanted item
Syntax and Examples
Using filter()
filter() is often the simplest way to remove an item by key.
const updatedUsers = users.filter(user => user.id !== 2);
This creates a new array containing every user except the one with id === 2.
Full example
type User = {
id: number;
name: string;
};
const users: User[] = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
const updatedUsers = users.filter(user => user.id !== 2);
console.log(updatedUsers);
// [
// { id: 1, name: "Alice" },
// { id: 3, name: "Charlie" }
// ]
Using findIndex() with splice()
If you need to change the original array, first find the index, then remove one item.
const index = users.findIndex(user => user.id === 2);
if (index !== -1) {
users.splice(index, 1);
}
Full example
type User = {
id: number;
name: string;
};
const users: User[] = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
const index = users.findIndex(user => user.id === 2);
if (index !== -1) {
users.splice(index, 1);
}
console.log(users);
// [
// { id: 1, name: "Alice" },
// { id: 3, name: "Charlie" }
// ]
Reusable helper function
function removeById(items: User[], id: number): User[] {
return items.filter(item => item.id !== id);
}
This is useful when the same logic appears in multiple places.
Step by Step Execution
Consider this example:
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
const updatedUsers = users.filter(user => user.id !== 2);
Step by step
userscontains 3 objects.filter()loops through each object one by one.- For
{ id: 1, name: "Alice" }, it checks1 !== 2.- This is
true, so Alice stays.
- This is
- For
{ id: 2, name: "Bob" }, it checks2 !== 2.- This is
false, so Bob is removed.
- This is
- For
{ id: 3, name: "Charlie" }, it checks3 !== 2.- This is
true, so Charlie stays.
- This is
filter()returns a new array with only Alice and Charlie.
Result:
[
{ id: 1, name: "Alice" },
{ id: 3, name: "Charlie" }
]
Now compare that with splice():
const index = users.findIndex(user => user.id === 2);
if (index !== -1) {
users.splice(index, 1);
}
What happens here
findIndex()loops through the array.- It returns the position of the first matching item.
- Bob is at index
1.
- Bob is at index
- The code checks
index !== -1.-1means no item was found.
users.splice(1, 1)removes 1 item starting at index 1.- The original
usersarray is changed directly.
Real World Use Cases
Removing array items by key appears in many real applications:
- Todo apps: remove a task by
id - Shopping carts: remove a product by
productId - Admin dashboards: delete a user from a displayed list
- API data handling: remove an item locally after a successful delete request
- Chat apps: remove a message or conversation from memory
- Data cleanup scripts: exclude records that match a certain key
Example: removing a product from a cart
type CartItem = {
productId: number;
name: string;
quantity: number;
};
const cart: CartItem[] = [
{ productId: 101, name: "Keyboard", quantity: 1 },
{ productId: 102, name: "Mouse", quantity: 2 }
];
const updatedCart = cart.filter(item => item.productId !== 102);
This pattern is especially common after a user clicks a Delete or Remove button.
Real Codebase Usage
In real projects, developers often choose the removal pattern based on state management and code clarity.
Immutable updates with filter()
This is common in frontend frameworks like React, where you should usually avoid mutating state directly.
setUsers(currentUsers => currentUsers.filter(user => user.id !== idToRemove));
Why this is common:
- easier to reason about
- safer for state updates
- works well with predictable rendering
Guard clauses with findIndex()
When mutating an array, developers usually protect against missing items.
const index = users.findIndex(user => user.id === idToRemove);
if (index === -1) return;
users.splice(index, 1);
This avoids accidental removal of the wrong item.
Validation before removal
In production code, the key may come from user input or an API.
function removeUser(users: User[], id: number): User[] {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return users.filter(user => user.id !== id);
}
Encapsulating logic in utility functions
Instead of repeating removal logic everywhere, teams often move it into reusable helpers.
function removeByKey<T, K extends keyof T>(items: T[], key: K, value: T[K]): T[] {
return items.filter(item => item[key] !== value);
}
Usage:
const result = removeByKey(users, "id", 2);
This pattern keeps code cleaner and more consistent.
Common Mistakes
1. Using delete on an array element
Broken code:
delete users[1];
This does not properly remove the item. It leaves an empty slot in the array.
Avoid it because:
- array length stays the same
- you may get unexpected
undefinedvalues
Use splice() or filter() instead.
2. Forgetting that filter() returns a new array
Broken code:
users.filter(user => user.id !== 2);
console.log(users);
This does nothing useful unless you store the result.
Correct:
const updatedUsers = users.filter(user => user.id !== 2);
Or reassign:
users = users.filter(user => user.id !== 2);
3. Calling splice() with -1
Broken code:
const index = users.findIndex(user => user.id === 999);
users.splice(index, 1);
If the item is not found, findIndex() returns -1. splice(-1, 1) removes the last item, which is usually a bug.
Correct:
const index = users.findIndex(user => user.id === 999);
if (index !== -1) {
users.splice(index, 1);
}
4. Comparing the wrong types
Broken code:
const idFromInput = "2";
const updatedUsers = users.filter(user => user.id !== idFromInput);
If user.id is a number, comparing it to a string can cause logic errors.
Correct:
const idFromInput = Number("2");
const updatedUsers = users.filter(user => user.id !== idFromInput);
5. Mutating when you meant to keep data immutable
Broken code for state-style logic:
users.splice(1, 1);
This may be fine in some cases, but not when your code expects a new array.
Prefer:
const updatedUsers = users.filter(user => user.id !== 2);
Comparisons
| Approach | Changes original array? | Returns new array? | Best for |
|---|---|---|---|
filter() | No | Yes | Immutable updates, cleaner code |
findIndex() + splice() | Yes | No | In-place removal |
delete arr[index] | Sort of, but incorrectly for removal | No | Usually avoid |
filter() vs splice()
Use filter() when:
- you want a new array
- you are working with state updates
- readability is more important than in-place modification
Use splice() when:
- you need to modify the existing array
- you already know the index or need in-place updates
find() vs findIndex()
| Method | Returns |
|---|---|
find() | The matching item |
findIndex() | The index of the matching item |
If you want to remove with splice(), you need the index, so findIndex() is usually the correct choice.
Cheat Sheet
Remove by key in TypeScript
Immutable approach
const updated = items.filter(item => item.id !== idToRemove);
- returns a new array
- original array stays unchanged
Mutable approach
const index = items.findIndex(item => item.id === idToRemove);
if (index !== -1) {
items.splice(index, 1);
}
- changes the original array
- always check for
-1
Generic helper
function removeByKey<T, K extends keyof T>(items: T[], key: K, value: T[K]): T[] {
return items.filter(item => item[key] !== value);
}
Avoid
delete items[1];
- leaves an empty slot
- does not truly remove the array element
Rules to remember
filter()is usually the safest and clearest choice.splice()removes by index, not by key.findIndex()returns-1if nothing matches.filter()must be assigned to a variable or returned.- Make sure key types match, such as
numbervsstring.
FAQ
How do I remove an object from an array by id in TypeScript?
Use filter() if you want a new array:
const updated = users.filter(user => user.id !== id);
Use findIndex() and splice() if you want to change the original array.
What is the best way to remove an item from an array in TypeScript?
For most cases, filter() is the best choice because it is simple, readable, and does not mutate the original array.
Can I use delete to remove an array item?
You can, but you usually should not. It leaves an empty slot instead of shifting the remaining items.
What happens if findIndex() does not find a match?
It returns -1. You should always check for that before calling splice().
Does filter() modify the original array?
No. It returns a new array.
Should I use splice() or filter() in React?
Usually filter(), because React state should generally be updated immutably.
Can I remove items by other keys besides id?
Yes. The same pattern works for any property, such as email, slug, or productId.
Mini Project
Description
Build a small TypeScript utility for managing a task list. Each task has an id, and you need to remove tasks by that id. This demonstrates the exact pattern used in real apps such as todo lists, admin panels, and client-side state updates.
Goal
Create a typed task list and remove a task by its id using an immutable approach.
Requirements
- Define a
Tasktype with at leastidandtitle. - Create an array with at least three task objects.
- Write a function that removes a task by
idusingfilter(). - Call the function and log the updated array.
- Keep the function type-safe with TypeScript annotations.
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.